home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Draw Editor / Source / ShapeCommands.cpp < prev    next >
Encoding:
Text File  |  1995-12-11  |  80.7 KB  |  2,751 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ShapeCommands.cpp
  3.  
  4.     Contains:    Shape command Classes Implementation
  5.  
  6.     Written by:    Dave Stafford
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- DrawEditor Includes --
  18.  
  19. #ifndef _PROMISE_
  20. #include "Promise.h"
  21. #endif
  22.  
  23. #ifndef _SHAPECOMMANDS_
  24. #include "ShapeCommands.h"
  25. #endif
  26.  
  27. #ifndef _SHAPES_
  28. #include "Shapes.h"
  29. #endif
  30.  
  31. #ifndef _SELECTION_
  32. #include "Selection.h"
  33. #endif
  34.  
  35. #ifndef _DRAWEDITORGLOBALS_
  36. #include "DrawEditorGlobals.h"
  37. #endif
  38.  
  39. #ifndef _DRAWEDITOR_
  40. #include "DrawEditor.h"
  41. #endif
  42.  
  43. #ifndef _DRAWEDITORUTILS_
  44. #include "DrawEditorUtils.h"
  45. #endif
  46.  
  47. #ifndef _PALETTE_
  48. #include "Palette.h"
  49. #endif
  50.  
  51. #ifndef _LINK_
  52. #include "Link.h"
  53. #endif
  54.  
  55. // -- OpenDoc Includes --
  56.  
  57. // for ODName  and ODByteArray
  58. #ifndef _ODTYPES_
  59. #include <ODTypes.h>
  60. #endif
  61.  
  62. #ifndef SOM_ODClipboard_xh
  63. #include <Clipbd.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODCMDDefs_xh
  67. #include <CMDDefs.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODDragAndDrop_xh
  71. #include <DragDrp.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODDragItemIterator_xh
  75. #include <DgItmIt.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODUndo_xh
  79. #include <Undo.xh>
  80. #endif
  81.  
  82. #ifndef SOM_ODFrame_xh
  83. #include <Frame.xh>
  84. #endif
  85.  
  86. #ifndef SOM_ODSession_xh
  87. #include <ODSessn.xh>
  88. #endif
  89.  
  90. #ifndef SOM_ODLinkSpec_xh
  91. #include <LinkSpec.xh>
  92. #endif
  93.  
  94. #ifndef SOM_ODLink_xh
  95. #include <Link.xh>
  96. #endif
  97.  
  98. // -- OpenDoc Utilities --
  99.  
  100. #ifndef _ODUTILS_
  101. #include "ODUtils.h"
  102. #endif
  103.  
  104. #ifndef _EXCEPT_
  105. #include "Except.h"
  106. #endif
  107.  
  108. #ifndef _STORUTIL_
  109. #include <StorUtil.h>
  110. #endif
  111.  
  112. #ifndef _ITEXT_
  113. #include "IText.h"
  114. #endif
  115.  
  116. #ifndef _ORDCOLL_
  117. #include "OrdColl.h"
  118. #endif
  119.  
  120. #ifndef _FOCUSLIB_
  121. #include "FocusLib.h"
  122. #endif
  123.  
  124. #ifndef _ODDEBUG_
  125. #include "ODDebug.h"
  126. #endif
  127.  
  128. #ifndef _ODMEMORY_
  129. #include "ODMemory.h"            // ODDisposePtr
  130. #endif
  131.  
  132. #ifndef _ISOSTR_
  133. #include "ISOStr.h"            // ODISOStrFromCStr
  134. #endif
  135.  
  136. // -- Toolbox Includes --
  137.  
  138. #ifndef mathRoutinesIncludes
  139. #include <math routines.h>
  140. #endif
  141.  
  142. #ifndef __MEMORY__
  143. #include <memory.h>
  144. #endif
  145.  
  146. #ifndef __OSUTILS__
  147. #include <OSUtils.h>
  148. #endif
  149.  
  150.  
  151.  
  152. // **************************** Need to improve Handling of Failure **********************
  153.  
  154. //=============================================================================
  155. // CModifySelectionCommand
  156. //=============================================================================
  157. CModifySelectionCommand::CModifySelectionCommand( DrawEditor* theEditor,
  158.                                                 CSelection* selection,
  159.                                                 ODBoolean canUndo,
  160.                                                 ODBoolean changesContent,
  161.                                                 ODID undoTextIndex,
  162.                                                 ODID redoTextIndex) :
  163. CCommand(theEditor, canUndo, changesContent, undoTextIndex, redoTextIndex)
  164. {
  165.     fSelection = selection;
  166.     fSavedShapes = kODNULL;
  167.     fSubscribeLinks = kODNULL;
  168. }
  169.  
  170.  
  171. //=============================================================================
  172. // CModifySelectionCommand
  173. //=============================================================================
  174. CModifySelectionCommand::~CModifySelectionCommand() 
  175. {
  176.     if (fSavedShapes)
  177.     {
  178.         delete fSavedShapes;
  179.         fSavedShapes = kODNULL;
  180.     }
  181.  
  182.     if (fSubscribeLinks)
  183.     {
  184.         delete fSubscribeLinks;
  185.         fSubscribeLinks = kODNULL;
  186.     }
  187. }
  188.  
  189.  
  190. //-----------------------------------------------------------------------------
  191. // CModifySelectionCommand::CaptureCommandState
  192. //
  193. // Here you want to make a copy of the selection so that derivative commands can
  194. // handle undo/redo correctly.
  195. //-----------------------------------------------------------------------------
  196.  
  197. void CModifySelectionCommand::CaptureCommandState(Environment* ev)
  198. {
  199.     // A move to another part is the only Undo-able drag action,
  200.     // So save undo state here in that case.
  201.     
  202.     // Only a cut is undo-able, but a copy needs to make the shape and subscribe link lists
  203.     // available to the pending publish link.
  204.     
  205.     fSavedShapes = new COrderedList;
  206.     COrdListIterator iter(fSelection->GetShapeList());
  207.     for (CShape* shape = (CShape*)iter.First();
  208.         iter.IsNotComplete(); 
  209.         shape = (CShape*)iter.Next())
  210.     {
  211.         if (!shape->IsSubscribed())
  212.             fSavedShapes->AddLast(shape);
  213.     }
  214.  
  215.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  216. }
  217.  
  218. //-----------------------------------------------------------------------------
  219. // CModifySelectionCommand::UndoCommand
  220. //-----------------------------------------------------------------------------
  221.  
  222. void CModifySelectionCommand::UndoCommand(Environment* ev)
  223. {
  224.     // Call Inherited
  225.     CCommand::UndoCommand(ev);
  226.     
  227.     // Add the saved shapes to the selection
  228.     this->SelectModifiedShapes(ev);
  229.  
  230.     //  Call selection changed before adding back any publishers. That way, 
  231.     // They won't be updated. Publishers that are entirely contained in content
  232.     // being removed should not propagate updates, therefore don't need to when they
  233.     // are added back in again.
  234.     
  235.     fSelection->SelectedContentUpdated(ev);
  236.     
  237. }
  238.  
  239.  
  240. //-----------------------------------------------------------------------------
  241. // CModifySelectionCommand::RedoCommand
  242. //-----------------------------------------------------------------------------
  243.  
  244. void CModifySelectionCommand::RedoCommand(Environment* ev)
  245. {
  246.     // Call Inherited
  247.     CCommand::RedoCommand(ev);
  248.     
  249.     // Select saved shapes
  250.     this->SelectModifiedShapes(ev);    
  251. }
  252.  
  253. //-----------------------------------------------------------------------------
  254. // CModifySelectionCommand::SelectModifiedShapes
  255. //-----------------------------------------------------------------------------
  256.  
  257. void CModifySelectionCommand::SelectModifiedShapes(Environment* ev)
  258. {
  259.     fSelection->CloseSelection(ev);
  260.     
  261.     COrdListIterator iter(fSavedShapes);
  262.     for (CShape* shape = (CShape*)iter.First();
  263.         iter.IsNotComplete(); 
  264.         shape = (CShape*)iter.Next())
  265.     {
  266.         fSelection->AddToSelection(ev, shape, kODFalse);
  267.     }
  268.     
  269.     COrdListIterator iter2(fSubscribeLinks);
  270.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  271.         iter2.IsNotComplete(); 
  272.         link = (CSubscribeLink*)iter2.Next())
  273.     {
  274.         link->AddToSelection(ev, kODFalse);
  275.     }
  276. }
  277.  
  278.  
  279. //=============================================================================
  280. // CNewShapeCommand
  281. //=============================================================================
  282.  
  283. //-----------------------------------------------------------------------------
  284. // CNewShapeCommand::CNewShapeCommand
  285. //-----------------------------------------------------------------------------
  286.  
  287. CNewShapeCommand::CNewShapeCommand( DrawEditor* theEditor,
  288.                                     ODFacet* sourceFacet,
  289.                                     Rect& bounds,
  290.                                     CRGBColor& color,
  291.                                     ODSShort shapeType,
  292.                                     CSelection* selection) :
  293. CCommand(theEditor, kODTrue, kODTrue, kUndoNewShapeIndex, kRedoNewShapeIndex)
  294. {
  295.     fShapeColor = color;
  296.     fShapeBounds = bounds;
  297.     fShape = kODNULL;
  298.     fSelection = selection;
  299.     fShapeType = shapeType;
  300.     fSourceFacet = sourceFacet;
  301. }
  302.  
  303.  
  304. //-----------------------------------------------------------------------------
  305. // CNewShapeCommand::~CNewShapeCommand
  306. //-----------------------------------------------------------------------------
  307.  
  308. CNewShapeCommand::~CNewShapeCommand()
  309. {
  310.     fDrawEditor = kODNULL;
  311.     fSourceFacet = kODNULL;
  312. }
  313.  
  314. //-----------------------------------------------------------------------------
  315. // CNewShapeCommand::DoCommand
  316. //-----------------------------------------------------------------------------
  317.  
  318. void CNewShapeCommand::DoCommand(Environment* ev)
  319. {
  320.     // Call inherited
  321.     CCommand::DoCommand(ev);
  322.     
  323.     // We are creating a new shape. The new shape 
  324.     // should be the only thing selected afterwards
  325.     fSelection->CloseSelection(ev);
  326.     
  327.     // If the shapetype is kEmbeddingShape then
  328.     // construct on of those,
  329.     if (fShapeType==kEmbeddingShape)
  330.     {
  331.         // The user is requesting a text shape
  332.         // Call the draft to create a part of the kind we are interested in
  333.         ODPart* textPart = fDrawEditor->GetDraft(ev)->CreatePart(ev, gGlobals->fCurrentTextPartKind, kODNULL);
  334.         THROW_IF_NULL(textPart);
  335.         
  336.         // We must externalize the newly created part, so that it will have
  337.         // a valid contents property
  338.         textPart->Externalize(ev);
  339.         
  340.         // Create a content shape
  341.         fShape = fDrawEditor->CreateShape(ev, fShapeType, fShapeBounds);
  342.         
  343.         // Embed the part, CEmbeddingShape::Embed will release the part passed to it.
  344.         ((CEmbeddingShape*)fShape)->Embed(ev, textPart, fSourceFacet->GetFrame(ev), kODNULL);
  345.         
  346.         // Release the newly created part
  347.         ODReleaseObject(ev, textPart);
  348.     }
  349.     else
  350.     {
  351.         // Otherwise, Create a regular shape.
  352.         fShape = fDrawEditor->CreateShape(ev, fShapeType, fShapeBounds);
  353.         THROW_IF_NULL(fShape);
  354.             
  355.         fShape->SetColor(fShapeColor);
  356.     }
  357.     
  358.     // Add the shape to the content list
  359.     fDrawEditor->AddShape(ev, fShape);
  360.     
  361.     // Add the shape to the selection
  362.     fSelection->AddToSelection(ev, fShape, kODTrue);
  363.  
  364.     fDrawEditor->ContentUpdated(ev, kODNULL);
  365. }
  366.  
  367.  
  368. //-----------------------------------------------------------------------------
  369. // CNewShapeCommand::UndoCommand
  370. //-----------------------------------------------------------------------------
  371.  
  372. void CNewShapeCommand::UndoCommand(Environment* ev)
  373. {
  374.     // Call Inherited
  375.     CCommand::UndoCommand(ev);
  376.     
  377.     fSelection->RemoveFromSelection(ev, fShape, kODTrue);
  378.     fDrawEditor->RemoveShape(ev, fShape);
  379.     
  380.     fDrawEditor->ContentUpdated(ev, kODNULL);
  381. }
  382.  
  383.  
  384. //-----------------------------------------------------------------------------
  385. // CNewShapeCommand::RedoCommand
  386. //-----------------------------------------------------------------------------
  387.  
  388. void CNewShapeCommand::RedoCommand(Environment* ev)
  389. {
  390.     // Call Inherited
  391.     CCommand::RedoCommand(ev);
  392.     
  393.     // Add the shape to the selection
  394.     fSelection->AddToSelection(ev, fShape, kODTrue);
  395.     fDrawEditor->AddShape(ev, fShape);
  396.     
  397.     fDrawEditor->ContentUpdated(ev, kODNULL);
  398. }
  399.  
  400.  
  401. //-----------------------------------------------------------------------------
  402. // CNewShapeCommand::Commit
  403. //
  404. // Here you want to clean up command specific structures depnding on the value of state.
  405. // For example, if a command creates a new piece of content and is comitted after being undone
  406. // then it should delete the structure representing the new content. Otherwise, it should not
  407. // deleted.
  408. //-----------------------------------------------------------------------------
  409.  
  410. void CNewShapeCommand::Commit(Environment* ev, ODDoneState state)
  411. {
  412.     CCommand::Commit(ev, state);
  413.     
  414.     // Create temp list to pass to CheckAndResolvePromisedShapes
  415.     COrderedList tList;
  416.     tList.AddLast(fShape);
  417.     CheckAndResolvePromisedShapes(ev, &tList, fDrawEditor->GetSession(ev));
  418.     
  419.     // If the command was undone, then delete the shape
  420.     if ((state==kODUndone)&&(fShape))
  421.     {
  422.         fShape->SetInLimbo(ev, kODTrue);
  423.         fShape->Removed(ev, kCommit);
  424.         delete fShape;
  425.     }
  426.     fShape = kODNULL;
  427. }
  428.  
  429.  
  430. //-----------------------------------------------------------------------------
  431. // CNewShapeCommand::CaptureCommandState
  432. //
  433. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  434. // Example: You might make a copy of a list of references to content that is being operated on
  435. // by the command.
  436. //-----------------------------------------------------------------------------
  437.  
  438. void CNewShapeCommand::CaptureCommandState(Environment* ev)
  439. {
  440.  
  441. }
  442.  
  443. //=============================================================================
  444. // CMoveShapeCommand
  445. //=============================================================================
  446.  
  447. //-----------------------------------------------------------------------------
  448. // CMoveShapeCommand::CMoveShapeCommand
  449. //
  450. // Since this command is used for four different actions, we pass zeroes to
  451. // the base class for undo/redo string IDs and set them to the correct values
  452. // later.
  453. //-----------------------------------------------------------------------------
  454.  
  455. CMoveShapeCommand::CMoveShapeCommand(DrawEditor* theEditor,
  456.                         ODFrame* sourceFrame,
  457.                         ODCommandID moveType,
  458.                         CSelection* selection) :
  459. CCommand(theEditor, kODTrue, kODTrue, 
  460.                 0, 0)
  461. {
  462.     fMoveType = moveType;
  463.     fSelection = selection;
  464.     fSourceFrame = sourceFrame;
  465.     fSavedShapes = kODNULL;
  466.     
  467.     // Set up the correct undo/redo strings for this instance of the command
  468.     switch ( fMoveType )
  469.     {
  470.         // Drawing Commands
  471.         case kMoveForwardCmd:
  472.             this->SetMenuTextIDs(kUndoMoveForwardIndex, kRedoMoveForwardIndex);
  473.             break;
  474.             
  475.         case kMoveFrontCmd:
  476.             this->SetMenuTextIDs(kUndoMoveFrontIndex, kRedoMoveFrontIndex);
  477.             break;
  478.         
  479.         case kMoveBackwardCmd:
  480.             this->SetMenuTextIDs(kUndoMoveBackwardIndex, kRedoMoveBackwardIndex);
  481.             break;
  482.  
  483.         case kMoveBackCmd:
  484.             this->SetMenuTextIDs(kUndoMoveBackIndex, kRedoMoveBackIndex);
  485.             break;
  486.         
  487.         default:
  488.             THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
  489.     }
  490.  
  491. }
  492.  
  493.  
  494. //-----------------------------------------------------------------------------
  495. // CMoveShapeCommand::~CMoveShapeCommand
  496. //-----------------------------------------------------------------------------
  497.  
  498. CMoveShapeCommand::~CMoveShapeCommand()
  499. {
  500.     fDrawEditor = NULL;
  501.     fSourceFrame = NULL;
  502.     
  503.     if (fSavedShapes)
  504.     {
  505.         delete fSavedShapes;
  506.         fSavedShapes = kODNULL;
  507.     }
  508. }
  509.  
  510. //-----------------------------------------------------------------------------
  511. // CMoveShapeCommand::MoveShape
  512. //-----------------------------------------------------------------------------
  513.  
  514. void CMoveShapeCommand::MoveShape(Environment* ev, CShape* moveShape, CShape* shape)
  515. {
  516.     switch ( fMoveType )
  517.     {
  518.         // Drawing Commands
  519.         case kMoveForwardCmd:
  520.         case kMoveFrontCmd:
  521.             fDrawEditor->MoveShapeBefore(ev, moveShape, shape);
  522.             break;
  523.         
  524.         case kMoveBackwardCmd:
  525.         case kMoveBackCmd:
  526.             fDrawEditor->MoveShapeAfter(ev, moveShape, shape);
  527.             break;
  528.         
  529.         default:
  530.             THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
  531.     }
  532. }
  533.  
  534. //-----------------------------------------------------------------------------
  535. // CMoveShapeCommand::FindReferenceShape
  536. //-----------------------------------------------------------------------------
  537.  
  538. CShape* CMoveShapeCommand::FindReferenceShape(Environment* ev, CShape* moveShape)
  539. {
  540.     COrderedList* tShapeList = fDrawEditor->GetShapeList();
  541.     
  542.     switch ( fMoveType )
  543.     {
  544.         // Drawing Commands
  545.         case kMoveForwardCmd:
  546.             return (CShape*)tShapeList->Before(moveShape);
  547.             break;
  548.             
  549.         case kMoveFrontCmd:
  550.             return (CShape*)tShapeList->First(); 
  551.             break;
  552.         
  553.         case kMoveBackwardCmd:
  554.             return (CShape*)tShapeList->After(moveShape);
  555.             break;
  556.         
  557.         case kMoveBackCmd:
  558.             return (CShape*)tShapeList->Last(); 
  559.             break;
  560.         
  561.         default:
  562.             THROW(kODErrInvalidParameter, "Passed invalid move type to move shape command!");
  563.     }
  564.     
  565.     return kODNULL;
  566. }
  567.  
  568. //-----------------------------------------------------------------------------
  569. // CMoveShapeCommand::DoCommand
  570. //-----------------------------------------------------------------------------
  571.  
  572. void CMoveShapeCommand::DoCommand(Environment* ev)
  573. {
  574.     // Call inherited
  575.     CCommand::DoCommand(ev);
  576.     
  577.     // If any of the shapes in the selection we are operating on have
  578.     // already been promised t othe clipboard, then we need to resolve
  579.     // the promise on the clipoard to ensure that it will not be corrupted.
  580.     if (fSelection->IsPromisedToClipboard())
  581.     {
  582.         ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
  583.     }
  584.     
  585.     COrdListIterator ite(fSelection->GetShapeList());
  586.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  587.     {
  588.         CShape* tShape = this->FindReferenceShape(ev, shape);
  589.         
  590.         // The way the MoveShape method actually moves a shape is to first remove
  591.         // it from the list, then add it back to the list relative to the ref
  592.         // shape. Well, obviously, if the ref & move shapes are the same shape
  593.         // this will *not* work.
  594.         if (shape!=tShape)
  595.             this->MoveShape(ev, shape, tShape);
  596.     }
  597.     
  598.     fSelection->InvalidateSelection(ev, fSourceFrame);
  599.     fSelection->SelectedContentUpdated(ev);
  600. }
  601.  
  602.  
  603. //-----------------------------------------------------------------------------
  604. // CMoveShapeCommand::UndoCommand
  605. //-----------------------------------------------------------------------------
  606.  
  607. void CMoveShapeCommand::UndoCommand(Environment* ev)
  608. {
  609.     // Call Inherited
  610.     CCommand::UndoCommand(ev);
  611.     
  612.     // Get the first saved shape and reset the iter
  613.     COrdListIterator savedShapeIter(fSavedShapes);
  614.     CShape* tShape = (CShape*)savedShapeIter.First();
  615.     
  616.     COrdListIterator ite(fSelection->GetShapeList());
  617.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  618.     {
  619.         if (tShape!=kODNULL)
  620.             fDrawEditor->MoveShapeBefore(ev, shape, tShape);
  621.     
  622.         CShape* tShape = (CShape*)savedShapeIter.Next();
  623.     }
  624.     
  625.     fSelection->InvalidateSelection(ev, fSourceFrame);
  626.     fSelection->SelectedContentUpdated(ev);
  627. }
  628.  
  629.  
  630. //-----------------------------------------------------------------------------
  631. // CMoveShapeCommand::RedoCommand
  632. //-----------------------------------------------------------------------------
  633.  
  634. void CMoveShapeCommand::RedoCommand(Environment* ev)
  635. {
  636.     // Call Inherited
  637.     CCommand::RedoCommand(ev);
  638.     
  639.     COrdListIterator ite(fSelection->GetShapeList());
  640.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  641.     {
  642.         CShape* tShape = this->FindReferenceShape(ev, shape);
  643.         
  644.         // The way the MoveShape method actually moves a shape is to first remove
  645.         // it from the list, then add it back to the list relative to the ref
  646.         // shape. Well, obviously, if the ref & move shapes are the same shape
  647.         // this will *not* work.
  648.         if (shape!=tShape)
  649.             this->MoveShape(ev, shape, tShape);
  650.     }
  651.     
  652.     fSelection->InvalidateSelection(ev, fSourceFrame);
  653.     fSelection->SelectedContentUpdated(ev);
  654. }
  655.  
  656.  
  657. //-----------------------------------------------------------------------------
  658. // CMoveShapeCommand::Commit
  659. //
  660. // Here you want to clean up command specific structures depending on the value of state.
  661. // For example, if a command creates a new piece of content and is comitted after being undone
  662. // then it should delete the structure representing the new content. Otherwise, it should not
  663. // deleted.
  664. //-----------------------------------------------------------------------------
  665.  
  666. void CMoveShapeCommand::Commit(Environment* ev, ODDoneState state)
  667. {
  668.     CCommand::Commit(ev, state);
  669. }
  670.  
  671.  
  672. //-----------------------------------------------------------------------------
  673. // CMoveShapeCommand::CaptureCommandState
  674. //
  675. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  676. // Example: You might make a copy of a list of references to content that is being operated on
  677. // by the command.
  678. //-----------------------------------------------------------------------------
  679.  
  680. void CMoveShapeCommand::CaptureCommandState(Environment* ev)
  681. {
  682.     // List of shapes being operated on
  683.     COrderedList* tShapeList = fDrawEditor->GetShapeList();
  684.     
  685.     // Allocate a list to store shapes for undo/redo
  686.     fSavedShapes = new COrderedList;
  687.     
  688.     // Save off the "after" shape of each shape in the selection
  689.     // so we can reconstitute the correct order when a "redo" occurs.
  690.     COrdListIterator ite(fSelection->GetShapeList());
  691.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  692.     {
  693.         CShape* tShape = (CShape*)tShapeList->After(shape);
  694.         fSavedShapes->AddFirst(tShape);
  695.     }
  696.     
  697. }
  698.  
  699.  
  700. //=============================================================================
  701. // CResizeSelectionCommand
  702. //=============================================================================
  703.  
  704. //-----------------------------------------------------------------------------
  705. // CResizeSelectionCommand::CResizeSelectionCommand
  706. //-----------------------------------------------------------------------------
  707.  
  708. CResizeSelectionCommand::CResizeSelectionCommand(DrawEditor* theEditor,
  709.                                                     ODFacet* sourceFacet,
  710.                                                     CSelection* selection,
  711.                                                     Rect& baseRect,
  712.                                                     Rect& resizeRect) :
  713. CModifySelectionCommand(theEditor, selection, kODTrue, kODTrue, kUndoResizeIndex, kRedoResizeIndex)
  714. {
  715.     fBaseRect = baseRect;
  716.     fResizeRect = resizeRect;
  717.  
  718.     fSourceFacet = sourceFacet;
  719.     fDrawEditor = theEditor;
  720. }
  721.  
  722.  
  723. //-----------------------------------------------------------------------------
  724. // CResizeSelectionCommand::~CResizeSelectionCommand
  725. //-----------------------------------------------------------------------------
  726.  
  727. CResizeSelectionCommand::~CResizeSelectionCommand()
  728. {
  729. }
  730.  
  731.  
  732. //-----------------------------------------------------------------------------
  733. // CResizeSelectionCommand::DoCommand
  734. //-----------------------------------------------------------------------------
  735.  
  736. void CResizeSelectionCommand::DoCommand(Environment* ev)
  737. {
  738.     // Call inherited
  739.     CCommand::DoCommand(ev);
  740.     
  741.     // If any of the shapes in the selection we are operating on have
  742.     // already been promised t othe clipboard, then we need to resolve
  743.     // the promise on the clipoard to ensure that it will not be corrupted.
  744.     if (fSelection->IsPromisedToClipboard())
  745.     {
  746.         ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
  747.     }
  748.     
  749.     fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fBaseRect, fResizeRect);
  750.     fSelection->SelectedContentUpdated(ev);
  751. }
  752.  
  753.  
  754. //-----------------------------------------------------------------------------
  755. // CResizeSelectionCommand::UndoCommand
  756. //-----------------------------------------------------------------------------
  757.  
  758. void CResizeSelectionCommand::UndoCommand(Environment* ev)
  759. {
  760.     // Call Inherited
  761.     CModifySelectionCommand::UndoCommand(ev);
  762.     
  763.     fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fResizeRect, fBaseRect);
  764.     fSelection->SelectedContentUpdated(ev);
  765. }
  766.  
  767.  
  768. //-----------------------------------------------------------------------------
  769. // CResizeSelectionCommand::RedoCommand
  770. //-----------------------------------------------------------------------------
  771.  
  772. void CResizeSelectionCommand::RedoCommand(Environment* ev)
  773. {
  774.     // Call Inherited
  775.     CModifySelectionCommand::RedoCommand(ev);
  776.  
  777.     fSelection->ResizeSelection(ev, fSourceFacet->GetFrame(ev), fBaseRect, fResizeRect);
  778.     fSelection->SelectedContentUpdated(ev);
  779. }
  780.  
  781.  
  782. //-----------------------------------------------------------------------------
  783. // CResizeSelectionCommand::Commit
  784. //
  785. // Here you want to clean up command specific structures depnding on the value of state.
  786. // For example, if a command creates a new piece of content and is comitted after being undone
  787. // then it should delete the structure representing the new content. Otherwise, it should not
  788. // deleted.
  789. //-----------------------------------------------------------------------------
  790.  
  791. void CResizeSelectionCommand::Commit(Environment* ev, ODDoneState state)
  792. {
  793.     CCommand::Commit(ev, state);
  794. }
  795.  
  796.  
  797. //-----------------------------------------------------------------------------
  798. // CResizeSelectionCommand::CaptureCommandState
  799. //
  800. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  801. // Example: You might make a copy of a list of references to content that is being operated on
  802. // by the command.
  803. //-----------------------------------------------------------------------------
  804.  
  805. void CResizeSelectionCommand::CaptureCommandState(Environment* ev)
  806. {
  807.     CModifySelectionCommand::CaptureCommandState(ev);
  808. }
  809.  
  810.  
  811. //=============================================================================
  812. // CColorSelectionCommand::CColorSelectionCommand
  813. //=============================================================================
  814.  
  815. //-----------------------------------------------------------------------------
  816. // CColorSelectionCommand::CColorSelectionCommand
  817. //-----------------------------------------------------------------------------
  818.  
  819. CColorSelectionCommand::CColorSelectionCommand(DrawEditor* theEditor,
  820.                                                 CSelection* selection,
  821.                                                 CRGBColor& newColor) :
  822. CCommand(theEditor, kODTrue, kODTrue, kUndoColorChangeIndex, kRedoColorChangeIndex)
  823. {
  824.     fColor = newColor;
  825.  
  826.     fSavedColors = new COrderedList;
  827.     fDrawEditor = theEditor;
  828.     fSelection = selection;
  829. }
  830.  
  831.  
  832. //-----------------------------------------------------------------------------
  833. // CColorSelectionCommand::~CRGBColorSelectionCommand
  834. //-----------------------------------------------------------------------------
  835.  
  836. CColorSelectionCommand::~CColorSelectionCommand()
  837. {
  838.     if (fSavedColors)
  839.     {
  840.         fSavedColors->DeleteAllLinks();
  841.         delete fSavedColors;
  842.     }
  843. }
  844.  
  845.  
  846. //-----------------------------------------------------------------------------
  847. //CColorSelectionCommand::DoCommand
  848. //-----------------------------------------------------------------------------
  849.  
  850. void CColorSelectionCommand::DoCommand(Environment* ev)
  851. {
  852.     // Call inherited
  853.     CCommand::DoCommand(ev);
  854.     
  855.     // If any of the shapes in the selection we are operating on have
  856.     // already been promised t othe clipboard, then we need to resolve
  857.     // the promise on the clipoard to ensure that it will not be corrupted.
  858.     if (fSelection->IsPromisedToClipboard())
  859.     {
  860.         ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
  861.     }
  862.     
  863.     COrdListIterator iter(fSelection->GetShapeList());
  864.     for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
  865.     {
  866.         // Save the old rectangle for undo
  867.         CRGBColor* savedColor = new CRGBColor(*shape->GetColor());
  868.         fSavedColors->AddLast(savedColor);
  869.         
  870.         // Invalidate old shape
  871.         fDrawEditor->InvalidateShape(ev, shape);
  872.         
  873.         // Recolor the shape
  874.         shape->SetColor(fColor);
  875.         
  876.         // Draw new shape
  877.         fDrawEditor->InvalidateShape(ev, shape);
  878.     }
  879.     fSelection->SelectedContentUpdated(ev);
  880. }
  881.  
  882.  
  883. //-----------------------------------------------------------------------------
  884. // CColorSelectionCommand::UndoCommand
  885. //-----------------------------------------------------------------------------
  886.  
  887. void CColorSelectionCommand::UndoCommand(Environment* ev)
  888. {
  889.     // Call Inherited
  890.     CCommand::UndoCommand(ev);
  891.     
  892.     
  893.     COrdListIterator iter2(fSavedColors);
  894.     CRGBColor* saved = (CRGBColor*)iter2.First();
  895.     
  896.     COrdListIterator iter(fSelection->GetShapeList());
  897.     for (CShape* shape = (CShape*)iter.First();
  898.             iter.IsNotComplete(); 
  899.             shape = (CShape*)iter.Next())
  900.     {
  901.         // Reset the shapes bounds to the pre-resized rectangle
  902.         shape->SetColor(*saved);
  903.         
  904.         // Redraw shape
  905.         fDrawEditor->InvalidateShape(ev, shape);
  906.         
  907.         saved = (CRGBColor*)iter2.Next();
  908.     }
  909.     fSelection->SelectedContentUpdated(ev);
  910. }
  911.  
  912.  
  913. //-----------------------------------------------------------------------------
  914. // CColorSelectionCommand::RedoCommand
  915. //-----------------------------------------------------------------------------
  916.  
  917. void CColorSelectionCommand::RedoCommand(Environment* ev)
  918. {
  919.     // Call Inherited
  920.     CCommand::RedoCommand(ev);
  921.     
  922.     COrdListIterator iter(fSelection->GetShapeList());
  923.     for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
  924.     {
  925.         // Don't need to save off the rects here because we already did in the DoCommand method
  926.         
  927.         // Restore shape color
  928.         shape->SetColor(fColor);
  929.         
  930.         // Redraw shape
  931.         fDrawEditor->InvalidateShape(ev, shape);
  932.     }
  933.     fSelection->SelectedContentUpdated(ev);
  934. }
  935.  
  936.  
  937. //-----------------------------------------------------------------------------
  938. // CColorSelectionCommand::Commit
  939. //
  940. // Here you want to clean up command specific structures depnding on the value of state.
  941. // For example, if a command creates a new piece of content and is comitted after being undone
  942. // then it should delete the structure representing the new content. Otherwise, it should not
  943. // deleted.
  944. //-----------------------------------------------------------------------------
  945.  
  946. void CColorSelectionCommand::Commit(Environment* ev, ODDoneState state)
  947. {
  948.     CCommand::Commit(ev, state);
  949. }
  950.  
  951.  
  952. //-----------------------------------------------------------------------------
  953. //CColorSelectionCommand::CaptureCommandState
  954. //
  955. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  956. // Example: You might make a copy of a list of references to content that is being operated on
  957. // by the command.
  958. //-----------------------------------------------------------------------------
  959.  
  960. void CColorSelectionCommand::CaptureCommandState(Environment* ev)
  961. {
  962.  
  963. }
  964.  
  965.  
  966. //=============================================================================
  967. // CDragShapeCommand::CDragShapeCommand
  968. //=============================================================================
  969.  
  970. //-----------------------------------------------------------------------------
  971. // CDragShapeCommand::CDragShapeCommand
  972. //-----------------------------------------------------------------------------
  973.  
  974. CDragShapeCommand::CDragShapeCommand(DrawEditor* theEditor,
  975.                                         ODFacet* sourceFacet,
  976.                                         CSelection* selection,
  977.                                         ODEventData* event,
  978.                                         ODBoolean showFeedBack,
  979.                                         ODBoolean canUndo) :
  980. // CCommand(theEditor,  canUndo, kODFalse, kUndoCommandIndex, kRedoCommandIndex)
  981. CCommand(theEditor,  kODTrue, kODFalse, kUndoDragIndex, kRedoDragIndex)
  982. {
  983.     fEventData = event;
  984.     fShowDragFeedback = showFeedBack;
  985.     fDragResult = kODDropCopy;
  986.     fDragRegion = kODNULL;
  987.     
  988.     fSavedShapes = kODNULL;
  989.     fPublishLinks = kODNULL;
  990.     fSubscribeLinks = kODNULL;
  991.     
  992.     fSelection = selection;
  993.     fSourceFacet = sourceFacet;
  994.     
  995.     fDestinationPart = kODNULL;
  996.     fDrawEditor = theEditor;
  997.  
  998.     this->SetActionType(kODBeginAction);
  999.     
  1000.     fPublishLink = kODNULL;
  1001. }
  1002.  
  1003.  
  1004.  
  1005. //-----------------------------------------------------------------------------
  1006. // CDragShapeCommand::~CDragShapeCommand
  1007. //-----------------------------------------------------------------------------
  1008.  
  1009. CDragShapeCommand::~CDragShapeCommand()
  1010. {
  1011.     if (fDragRegion)
  1012.     {
  1013.         ::DisposeRgn(fDragRegion);
  1014.         fDragRegion = kODNULL;
  1015.     }
  1016.     
  1017.     if (fSavedShapes)
  1018.         delete fSavedShapes;
  1019.  
  1020.     if (fPublishLinks)
  1021.         delete fPublishLinks;
  1022.  
  1023.     if (fSubscribeLinks)
  1024.         delete fSubscribeLinks;
  1025. }
  1026.  
  1027.  
  1028. //-----------------------------------------------------------------------------
  1029. // CDragShapeCommand::CreateDragShape
  1030. //-----------------------------------------------------------------------------
  1031.  
  1032. ODShape* CDragShapeCommand::CreateDragShape(Environment* ev, ODFacet* facet)
  1033. {
  1034.     return fSelection->CreateDragShape(ev, facet, fFrame);
  1035. }
  1036.  
  1037.  
  1038. //-----------------------------------------------------------------------------
  1039. // CDragShapeCommand::SelectDraggedShapes
  1040. //-----------------------------------------------------------------------------
  1041.  
  1042. void CDragShapeCommand::SelectDraggedShapes(Environment* ev)
  1043. {
  1044.     fSelection->CloseSelection(ev);
  1045.     
  1046.     COrdListIterator iter(fSavedShapes);
  1047.     for (CShape* shape = (CShape*)iter.First();
  1048.         iter.IsNotComplete(); 
  1049.         shape = (CShape*)iter.Next())
  1050.     {
  1051.         fSelection->AddToSelection(ev, shape, kODFalse);
  1052.     }
  1053.     
  1054.     COrdListIterator iter2(fSubscribeLinks);
  1055.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  1056.         iter2.IsNotComplete(); 
  1057.         link = (CSubscribeLink*)iter2.Next())
  1058.     {
  1059.         link->AddToSelection(ev, kODFalse);
  1060.     }
  1061. }
  1062.  
  1063.  
  1064. //-----------------------------------------------------------------------------
  1065. // CDragShapeCommand::Drag
  1066. //-----------------------------------------------------------------------------
  1067.  
  1068. ODBoolean CDragShapeCommand::Drag(Environment* ev, ODEventData* event)
  1069. {
  1070.     ODPart*            destination;
  1071.     ODDragAndDrop*    drag;
  1072.     ODStorageUnit*    dragSU;
  1073.     
  1074.     // Assume fSourceFacet is not null
  1075.     THROW_IF_NULL(fSourceFacet);
  1076.     
  1077.     // Fill the command's frame field
  1078.     fFrame = fSourceFacet->GetFrame(ev);
  1079.     
  1080.     // Get the Drag Shape & Transform it to window coordinates
  1081.     ODShape* dragShape = this->CreateDragShape(ev, fSourceFacet);
  1082.         
  1083.     // Get the drag region
  1084.     TRY
  1085.         fDragRegion = (RgnHandle)::ODCopyHandle((Handle)dragShape->GetQDRegion(ev));
  1086.     CATCH_ALL
  1087.         ODSafeReleaseObject(dragShape);
  1088.         return kODFalse;
  1089.     ENDTRY
  1090.     
  1091.     // Release ref counted geometry
  1092.     ODReleaseObject(ev, dragShape);
  1093.     
  1094.     // Focus for drawing
  1095.     {
  1096.         CFocus focus(ev, fSourceFacet);
  1097.         
  1098.         // Put the drag region into screen coordinates
  1099.         GrafPtr port;
  1100.         GetPort(&port);
  1101.         Point offset = {0, 0};
  1102.         ::LocalToGlobal(&offset);
  1103.         ::OffsetRgn(fDragRegion, offset.h, offset.v);
  1104.     }
  1105.     
  1106.     // Populate the drag & drop storage unit with drag data
  1107.     drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
  1108.     drag->Clear(ev);
  1109.     dragSU = drag->GetContentStorageUnit(ev);
  1110.     
  1111.     // Determine clone kind by whether the selection can be moved or only copied
  1112.     ODCloneKind cloneKind = fSelection->CanMoveSelectedContent() ? kODCloneCut : kODCloneCopy;
  1113.         
  1114.     // If we are dragging a single embedded shape then externalize 
  1115.     // as per that recipe
  1116.     CEmbeddingShape* tShape = fSelection->IsOneEmbeddedShape(ev);
  1117.     if (tShape!=kODNULL)
  1118.     {
  1119.         // Must find the embedded frame, so we can externalize it
  1120.         ODFrame* embeddedFrame = tShape->GetEmbeddedFacet(ev, fSourceFacet)->GetFrame(ev);            
  1121.                             
  1122.         // Build clone information
  1123.         CCloneInfo cloneInfo(0, fDrawEditor->GetDraft(ev), 
  1124.                                     fSourceFacet->GetFrame(ev), kODCloneCut);
  1125.                     
  1126.         // Externalize the frame
  1127.         fSelection->ExternalizeSingleEmbeddedFrame(ev, dragSU, &cloneInfo, embeddedFrame);
  1128.     }
  1129.     else
  1130.     // Otherwise, promise some data
  1131.     {
  1132.         // Focus to the content property
  1133.         ODSUForceFocus(ev, dragSU, kODPropContents, kDrawEditorKind);
  1134.         
  1135.         CCloneInfo cloneInfo(0, fDrawEditor->GetDraft(ev), 
  1136.                     fSourceFacet->GetFrame(ev), cloneKind);
  1137.         
  1138.         CPromise* promise = new CPromise(fDrawEditor, fSourceFacet->GetFrame(ev), fSelection, cloneKind );
  1139.         promise->Promise(ev, dragSU);
  1140.     }
  1141.         
  1142.     // Possible opportunity for factoring much of this and much of parallel code
  1143.     // in CCutCopyCommand into CPublishLink, but there are a few differences.
  1144.     
  1145.     ODBoolean doPublish = fSelection->CanPublish();
  1146.  
  1147.     if (doPublish)
  1148.     {
  1149.         // If current selection is already published, just re-use its publisher
  1150.         CPublishLink* publishLink = fSelection->FindPublisher();
  1151.         
  1152.         ODUpdateID updateID;
  1153.         
  1154.         // the publisher is the same one already spec'd on the clipboard then we have to 
  1155.         // preserve the id, cuz otherwise, the next pasteAs with link from the clipboard
  1156.         // will fail. So we'll just always re-use the existing pendingID always.
  1157.         
  1158.         if (publishLink && (publishLink == fDrawEditor->GetPendingPublish()))
  1159.             updateID = publishLink->GetPendingID();
  1160.         else
  1161.         {
  1162.             updateID = fDrawEditor->GetSession(ev)->UniqueUpdateID(ev);
  1163.             if (publishLink)
  1164.                 publishLink->SetPendingID(updateID);  // otherwise done in constructor later.
  1165.         }
  1166.         
  1167.         ODLinkSpec* linkSpec = kODNULL;
  1168.         ODVolatile(linkSpec);
  1169.         
  1170.         //  New recipe recommends that in the event that a link is created for the spec in the drag,
  1171.         //  the undo/redo of the drag becomes responsible for undo/redo of the link creation
  1172.         //    We were already using the updateID as a tag to determine which link is being created.
  1173.         //  We'll add a reference to this command. CreateLink, when it finds this reference, instead
  1174.         //     of creating a CCreateLinkCommand which adds a kODSingleAction, for a copy/pasteAs link,
  1175.         //  will pass the CPublishLink ref to this command so that it can control the undoing/redoing
  1176.         //  of the link.
  1177.         
  1178.         LinkSpecData  specData = {updateID, this};
  1179.         
  1180.         TRY
  1181.             ODByteArray data;
  1182.             data._buffer = (octet*)&specData;
  1183.             data._length = sizeof(specData);
  1184.             data._maximum = sizeof(specData);
  1185.     
  1186.             linkSpec = fDrawEditor->GetDraft(ev)->CreateLinkSpec(ev, fDrawEditor->GetODPart(), &data);
  1187.  
  1188.             dragSU->AddProperty(ev, kODPropLinkSpec);
  1189.             linkSpec->WriteLinkSpec(ev, dragSU);
  1190.             delete linkSpec;
  1191.         CATCH_ALL
  1192.             if (linkSpec)
  1193.                 delete linkSpec;
  1194.             doPublish = kODFalse;
  1195.         ENDTRY
  1196.         
  1197.         if (doPublish)
  1198.         {
  1199.             if (publishLink)
  1200.                 publishLink->SetPendingID(updateID);
  1201.             else
  1202.             {
  1203.             
  1204.                 // Have to provide copies of shape and subscribe link lists to the new publisher
  1205.                 // because if this turns out to be a move, we'll need the lists in our undo an redo code.
  1206.                 
  1207.                 publishLink = new CPublishLink( updateID, fSelection, 
  1208.                                                 new COrderedList(fSavedShapes), 
  1209.                                                 new COrderedList(fSubscribeLinks));
  1210.                 
  1211.             }
  1212.             
  1213.             fDrawEditor->SetPendingDragPublish(publishLink);
  1214.         }
  1215.     }
  1216.     
  1217.  
  1218.     // ----- Write id of source frame in case the drop occurs in the same frame.
  1219.     ODID frameID = fFrame->GetID(ev);
  1220.     dragSU->AddProperty(ev, kPropFrameInfo)->AddValue(ev, kODULong);
  1221.     StorageUnitSetValue(dragSU, ev, sizeof(ODID), &frameID);
  1222.         
  1223.     // We must notify all frames that we are dragging that they *are* being dragged.
  1224.     // This will prevent the frame being dragged from getting called for DragEnter, etc.
  1225.     fSelection->Dragging(ev, kODTrue);
  1226.     
  1227.     // Create structures for the StartDrag call
  1228.     ODByteArray dragByteArray;
  1229.     dragByteArray._length = sizeof(RgnHandle);
  1230.     dragByteArray._maximum = sizeof(RgnHandle);
  1231.     dragByteArray._buffer = (octet*)&fDragRegion;
  1232.     
  1233.     ODByteArray eventByteArray;
  1234.     eventByteArray._length = sizeof(ODEventData*);
  1235.     eventByteArray._maximum = sizeof(ODEventData*);
  1236.     eventByteArray._buffer = (octet*)&event;
  1237.     
  1238.     // Set the limbo status of any embedded frames in the current selection.
  1239.     fSelection->SetInLimbo(ev, kODTrue);
  1240.     
  1241.     // Start drag assumes that root facet is focused
  1242.     fDragResult = drag->StartDrag(ev, fFrame, kODDragImageRegionHandle, &dragByteArray, &destination, &eventByteArray);
  1243.  
  1244.     
  1245.     fDestinationPart = destination;
  1246.     
  1247.     // Release the destination part, if there was one 
  1248.     // since it is returned to us with a bumped ref count.
  1249.     ODReleaseObject(ev, destination);
  1250.  
  1251.     return kODTrue;
  1252. }
  1253.  
  1254. //-----------------------------------------------------------------------------
  1255. // CDragShapeCommand::DragCompleted
  1256. //-----------------------------------------------------------------------------
  1257.  
  1258. void CDragShapeCommand::DragCompleted(Environment* ev)
  1259. {
  1260.     // We must notify all frames that we are dragging that dragging has completed since
  1261.     // notified them earlier that they were being dragged. See earlier comment for 
  1262.     // explanation.
  1263.     fSelection->Dragging(ev, kODFalse);
  1264.  
  1265.     // If the destination was somewhere else AND the drag was a move
  1266.     // then get rid of the dragged shapes
  1267.     if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
  1268.     {
  1269.         ODBoolean tBoolean = fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev));
  1270.         if (!tBoolean)
  1271.         {
  1272.             DebugStr("\pClearSelection Failed!");
  1273.         }
  1274.     }
  1275.     else
  1276.         // If the drag was a copy, then any embedded frames that were put in limbo before
  1277.         // StartDrag should now be removed from limbo since they will remain in the current
  1278.         // document.
  1279.         if (fDragResult == kODDropCopy)
  1280.         {
  1281.             fSelection->SetInLimbo(ev, kODFalse);
  1282.         }
  1283.     
  1284.     // This is where we need to create an EndAction command, as per the
  1285.     // progammer's guide, the "dragger" is reponsible for both the begin
  1286.     // and end actions.
  1287.     if (fDragResult == kODDropUnfinished || fDragResult == kODDropFail)
  1288.     {
  1289.         this->AbortCommand(ev);
  1290.     }
  1291.     else
  1292.     {
  1293.         this->WriteAction(ev, kODEndAction);
  1294.         fTransactionClosed = kODTrue;
  1295.     }
  1296. }
  1297.  
  1298.  
  1299. //-----------------------------------------------------------------------------
  1300. // CDragShapeCommand::DoCommand
  1301. //-----------------------------------------------------------------------------
  1302.  
  1303. void CDragShapeCommand::DoCommand(Environment* ev)
  1304. {
  1305.     // Call inherited
  1306.     CCommand::DoCommand(ev);
  1307.     
  1308.     // If any of the shapes in the selection we are operating on have
  1309.     // already been promised t othe clipboard, then we need to resolve
  1310.     // the promise on the clipoard to ensure that it will not be corrupted.
  1311.     if (fSelection->IsPromisedToClipboard())
  1312.     {
  1313.         ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
  1314.     }
  1315.     
  1316.     if (fShowDragFeedback)
  1317.         this->Drag(ev, fEventData);
  1318.     // else
  1319.     // Need to set up structures to simulate drag for scripting. $$$$$.
  1320.     
  1321.     this->DragCompleted(ev);
  1322.     
  1323.     if (fDragRegion)
  1324.     {
  1325.         ::DisposeRgn(fDragRegion);
  1326.         fDragRegion = kODNULL;
  1327.     }
  1328. }
  1329.  
  1330.  
  1331. //-----------------------------------------------------------------------------
  1332. // CDragShapeCommand::UndoCommand
  1333. //-----------------------------------------------------------------------------
  1334.  
  1335. void CDragShapeCommand::UndoCommand(Environment* ev)
  1336. {
  1337.     // Call Inherited
  1338.     CCommand::UndoCommand(ev);
  1339.     
  1340.     if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
  1341.     {
  1342.         COrdListIterator iter(fSavedShapes);
  1343.         for (CShape* shape = (CShape*)iter.First();
  1344.             iter.IsNotComplete(); 
  1345.             shape = (CShape*)iter.Next())
  1346.         {
  1347.             fDrawEditor->AddShape(ev, shape);
  1348.         }
  1349.  
  1350.         COrdListIterator iter2(fSubscribeLinks);
  1351.         for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  1352.             iter2.IsNotComplete(); 
  1353.             link = (CSubscribeLink*)iter2.Next())
  1354.         {
  1355.             link->AddToPart(ev);
  1356.         }
  1357.     
  1358.         // Add the saved shapes to the selection
  1359.         this->SelectDraggedShapes(ev);
  1360.     
  1361.         // Call selection changed before adding back any publishers. That way, 
  1362.         // They won't be updated. Publishers that are entirely contained in content
  1363.         // being removed should not propagate updates, therefore don't need to when they
  1364.         // are added back in again.
  1365.         
  1366.         // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  1367.         fSelection->SelectedContentUpdated(ev);
  1368.         
  1369.         COrdListIterator iter3(fPublishLinks);
  1370.         for (CPublishLink* plink = (CPublishLink*)iter3.First();
  1371.             iter3.IsNotComplete(); 
  1372.             plink = (CPublishLink*)iter3.Next())
  1373.         {
  1374.             plink->AddToPart(ev);
  1375.         }
  1376.     }
  1377.     else if (fPublishLink)
  1378.     {
  1379.         fPublishLink->Unpublish(ev);
  1380.     }
  1381. }
  1382.  
  1383.  
  1384. //-----------------------------------------------------------------------------
  1385. // CDragShapeCommand::RedoCommand
  1386. //-----------------------------------------------------------------------------
  1387.  
  1388. void CDragShapeCommand::RedoCommand(Environment* ev)
  1389. {
  1390.     // Call Inherited
  1391.     CCommand::RedoCommand(ev);
  1392.     
  1393.     if (fDestinationPart != fDrawEditor->GetODPart()&&fDragResult == kODDropMove)
  1394.     {
  1395.         // Select saved shapes
  1396.         this->SelectDraggedShapes(ev);    
  1397.         
  1398.         // Put them back in limbo
  1399.         fSelection->SetInLimbo(ev, kODTrue);
  1400.         
  1401.         // clear them, again
  1402.         fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev)); 
  1403.     }
  1404.     else if (fPublishLink)
  1405.     {
  1406.         fPublishLink->Publish(ev);
  1407.     }
  1408. }
  1409.  
  1410.  
  1411. //-----------------------------------------------------------------------------
  1412. // CDragShapeCommand::Commit
  1413. //
  1414. // Here you want to clean up command specific structures depnding on the value of state.
  1415. // For example, if a command creates a new piece of content and is comitted after being undone
  1416. // then it should delete the structure representing the new content. Otherwise, it should not
  1417. // deleted.
  1418. //-----------------------------------------------------------------------------
  1419.  
  1420. void CDragShapeCommand::Commit(Environment* ev, ODDoneState state)
  1421. {
  1422.     CCommand::Commit(ev, state);
  1423.     
  1424.     if ( state != kODUndone && 
  1425.          fDragResult == kODDropMove && 
  1426.          fDestinationPart != fDrawEditor->GetODPart())
  1427.     {
  1428.         // Before removing / deleting shapes check to see if they
  1429.         // are promised to the clipboard.
  1430.         ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
  1431.         
  1432.         COrdListIterator iter(fSavedShapes);
  1433.         for (CShape* shape = (CShape*)iter.First();
  1434.             iter.IsNotComplete(); 
  1435.             shape = (CShape*)iter.Next())
  1436.         {
  1437.             shape->Removed(ev, kCommit);
  1438.             delete shape;
  1439.         }
  1440.  
  1441.         while (fSubscribeLinks->Count() != 0)
  1442.         {
  1443.             CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
  1444.             link->RemoveShapes(ev, kCommit);
  1445.             delete link;
  1446.         }
  1447.  
  1448.         while (fPublishLinks->Count() != 0)
  1449.         {
  1450.             CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
  1451.             delete link;
  1452.         }
  1453.     }
  1454.     
  1455.     // If a link was created, then undone, then we may have to dispose of it .
  1456.     else if (fPublishLink && state == kODUndone )
  1457.     {
  1458.         fPublishLink->SetHasCommandOutstanding(kODFalse);
  1459.     
  1460.         if (fDrawEditor->GetPendingPublish() != fPublishLink && fDrawEditor->GetPendingDragPublish() != fPublishLink)
  1461.             delete fPublishLink;
  1462.     }
  1463.     
  1464. }
  1465.  
  1466.  
  1467. //-----------------------------------------------------------------------------
  1468. // CDragShapeCommand::CaptureCommandState
  1469. //
  1470. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  1471. // Example: You might make a copy of a list of references to content that is being operated on
  1472. // by the command.
  1473. //-----------------------------------------------------------------------------
  1474.  
  1475. void CDragShapeCommand::CaptureCommandState(Environment* ev)
  1476. {
  1477.     // A move to another part is the only Undo-able drag action,
  1478.     // So save undo state here in that case.
  1479.     
  1480.     // Only a cut is undo-able, but a copy needs to make the shape and subscribe link lists
  1481.     // available to the pending publish link.
  1482.     
  1483.     fSavedShapes = new COrderedList;
  1484.     COrdListIterator iter(fSelection->GetShapeList());
  1485.     for (CShape* shape = (CShape*)iter.First();
  1486.         iter.IsNotComplete(); 
  1487.         shape = (CShape*)iter.Next())
  1488.     {
  1489.         if (!shape->IsSubscribed())
  1490.             fSavedShapes->AddLast(shape);
  1491.     }
  1492.     
  1493.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  1494.     
  1495.     // This data is only needed for an undoable move.  However, at this time, 
  1496.     // we don't know what were going to get!
  1497.     
  1498.     fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
  1499. }
  1500.  
  1501. //-----------------------------------------------------------------------------
  1502. // CDragShapeCommand::CreateLink
  1503. //
  1504. // Grab a CPublishLink reference for later undoing and redoing, and publish the link
  1505. // Does what a CCreateLinkCommand would do, but includes the link creation in the
  1506. // Drag/Drop undo/redo action.
  1507. //-----------------------------------------------------------------------------
  1508. void CDragShapeCommand::CreateLink(Environment* ev, CPublishLink* pLink)
  1509. {
  1510.     TRY
  1511.         pLink->Publish(ev);
  1512.         pLink->ContentUpdated(ev, fDrawEditor->GetSession(ev)->UniqueUpdateID(ev));
  1513.     CATCH_ALL
  1514.         if (!fTransactionClosed)
  1515.             this->AbortCommand(ev);
  1516.         
  1517.         RERAISE;
  1518.     ENDTRY
  1519.  
  1520.     pLink->SetHasCommandOutstanding(kODTrue);
  1521.     fPublishLink = pLink;
  1522.  
  1523. }
  1524.  
  1525.  
  1526. //=============================================================================
  1527. // CDropShapeCommand::CDropShapeCommand
  1528. //=============================================================================
  1529.  
  1530. //-----------------------------------------------------------------------------
  1531. // CDropShapeCommand::CDropShapeCommand
  1532. //-----------------------------------------------------------------------------
  1533.  
  1534. CDropShapeCommand::CDropShapeCommand(DrawEditor* theEditor,
  1535.                                         ODFacet* sourceFacet,
  1536.                                         ODDragItemIterator* dropInfo,
  1537.                                         CSelection* selection,
  1538.                                         ODPoint& dropPoint,
  1539.                                         ODBoolean canUndo) :
  1540. CCommand(theEditor,  canUndo, kODTrue, kUndoDropIndex, kRedoDropIndex)
  1541. {
  1542.     fDroppedInSameFrame = FALSE;
  1543.     fDropResult = kODDropFail;
  1544.     fDropPoint = dropPoint;
  1545.     fDropInfo = dropInfo;
  1546.     
  1547.     fSelection = selection;
  1548.     fSourceFacet = sourceFacet;
  1549.     
  1550.     fSavedShapes = kODNULL;
  1551.     fPublishLinks = kODNULL;
  1552.     fSubscribeLinks = kODNULL;
  1553. }
  1554.  
  1555.  
  1556.  
  1557. //-----------------------------------------------------------------------------
  1558. // CDropShapeCommand::~CDropShapeCommand
  1559. //-----------------------------------------------------------------------------
  1560.  
  1561. CDropShapeCommand::~CDropShapeCommand()
  1562. {
  1563.     if (fSavedShapes)
  1564.         delete fSavedShapes;
  1565.         
  1566.     if (fPublishLinks)
  1567.         delete fPublishLinks;
  1568.  
  1569.     if (fSubscribeLinks)
  1570.         delete fSubscribeLinks;
  1571.     
  1572. }
  1573.  
  1574.  
  1575. //-----------------------------------------------------------------------------
  1576. // CDropShapeCommand::GetDropResult
  1577. //-----------------------------------------------------------------------------
  1578.  
  1579. ODDropResult CDropShapeCommand::GetDropResult()
  1580. {
  1581.     return fDropResult;
  1582. }
  1583.  
  1584.  
  1585. //-----------------------------------------------------------------------------
  1586. // CDropShapeCommand::GetDropOrigin
  1587. //-----------------------------------------------------------------------------
  1588.  
  1589. void CDropShapeCommand::GetDropOrigin(Environment* ev, ODPoint* originPoint)
  1590. {
  1591.     // ----- Calculate originPoint (in content coordinate)
  1592.     Point dragOrigin;
  1593.     
  1594.     ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
  1595.     
  1596.     DragReference theDrag = drag->GetDragReference(ev);
  1597.     ::GetDragOrigin(theDrag, &dragOrigin);
  1598.     ::GlobalToLocal(&dragOrigin);
  1599.  
  1600.     *originPoint = dragOrigin;
  1601.         
  1602.     ODTransform* tTransform = fSourceFacet->AcquireWindowContentTransform(ev, NULL);
  1603.     tTransform->InvertPoint(ev, originPoint); // originPoint is modified in place
  1604.     
  1605.     ODReleaseObject(ev, tTransform);
  1606. }
  1607.  
  1608.  
  1609. //-----------------------------------------------------------------------------
  1610. // CDropShapeCommand::DoCommand
  1611. //-----------------------------------------------------------------------------
  1612.  
  1613. void CDropShapeCommand::DoCommand(Environment* ev)
  1614. {    
  1615.     TRY
  1616.         if (!fSourceFacet->GetFrame(ev)->IsDroppable(ev))
  1617.             fDropResult = kODDropFail;
  1618.         else
  1619.         {
  1620.             this->ExecuteDrop(ev);
  1621.         }
  1622.     
  1623.         this->AdjustUndo(ev);
  1624.         
  1625.         // Resolve the drop before we set the action history
  1626.         CCommand::DoCommand(ev);
  1627.         
  1628.         // if this was not a move within the same frame, then we have to add the subscribers and register them now.
  1629.         if (!fDroppedInSameFrame || (fDropResult == kODDropCopy))
  1630.         {
  1631.             COrdListIterator iter(fSubscribeLinks);
  1632.             for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
  1633.                 iter.IsNotComplete(); 
  1634.                 link = (CSubscribeLink*)iter.Next())
  1635.             {
  1636.                 link->AddToPart(ev);
  1637.             }
  1638.         }
  1639.     CATCH_ALL
  1640.         // ----- If we failed to drop, set the drop result to kODDropFail
  1641.         fDropResult = kODDropFail;
  1642.     ENDTRY
  1643. }
  1644.  
  1645.  
  1646. //-----------------------------------------------------------------------------
  1647. // CDropShapeCommand::AdjustUndo
  1648. //-----------------------------------------------------------------------------
  1649.  
  1650. void CDropShapeCommand::AdjustUndo(Environment* ev)
  1651. {
  1652.     if (fDropResult == kODDropFail)                // Drop failed--can't Undo
  1653.     {
  1654.         fCanUndo = FALSE;                        // Don't call AddActionToHistory
  1655.         fChangesContent = FALSE;                // Don't call fPart->Changed()
  1656.     }
  1657.     else 
  1658.     // According to Programmer's guide Drop is always a single action. Drag
  1659.     // should specify both begin & end. 
  1660.         this->SetActionType(kODSingleAction);    
  1661. }
  1662.  
  1663. //-----------------------------------------------------------------------------
  1664. // CDropShapeCommand::Commit
  1665. //
  1666. // Here you want to clean up command specific structures depnding on the value of state.
  1667. // For example, if a command creates a new piece of content and is comitted after being undone
  1668. // then it should delete the structure representing the new content. Otherwise, it should not
  1669. // deleted.
  1670. //-----------------------------------------------------------------------------
  1671.  
  1672. void CDropShapeCommand::Commit(Environment* ev, ODDoneState state)
  1673. {
  1674.     CCommand::Commit(ev, state);
  1675.     
  1676.     // If the command was Done or Redone and it was not a drop move 
  1677.     // ( shapes were dragged out of document ) then we should delete the 
  1678.     // shapes in the saved shape list.
  1679.     if (((state==kODUndone)&&fDropResult!=kODDropMove))
  1680.     {
  1681.         // Before removing / deleting shapes check to see if they
  1682.         // are promised to the clipboard.
  1683.         ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
  1684.         
  1685.         COrdListIterator iter(fSavedShapes);
  1686.         for (CShape* shape = (CShape*)iter.First();
  1687.             iter.IsNotComplete(); 
  1688.             shape = (CShape*)iter.Next())
  1689.         {
  1690.             shape->SetInLimbo(ev, kODTrue);
  1691.             shape->Removed(ev, kCommit);
  1692.             delete shape;
  1693.         
  1694.             while (fSubscribeLinks->Count() != 0)
  1695.             {
  1696.                 CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
  1697.                 link->RemoveShapes(ev, kCommit);
  1698.                 delete link;
  1699.             }
  1700.             
  1701.             while (fPublishLinks->Count() != 0)
  1702.             {
  1703.                 CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
  1704.                 delete link;
  1705.             }
  1706.         }
  1707.     }
  1708.  
  1709. }
  1710.  
  1711.  
  1712. //----------------------------------------------------------------------------------------
  1713. // CDropShapeCommand::DoDroppedInSameFrame
  1714. //----------------------------------------------------------------------------------------
  1715.  
  1716. ODBoolean CDropShapeCommand::DoDroppedInSameFrame(Environment* ev,
  1717.                                                  ODStorageUnit* dropSU,
  1718.                                                  ODPoint& originPoint, 
  1719.                                                  ODPoint& dropPoint)
  1720. {
  1721.     fDropOffset = dropPoint;
  1722.     fDropOffset -= originPoint;
  1723.     
  1724.     TRY
  1725.         // Offset the selection
  1726.         fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), fDropOffset.x, fDropOffset.y);
  1727.     CATCH_ALL
  1728.         return kODFalse;
  1729.     ENDTRY
  1730.     
  1731.     return kODTrue;
  1732. }
  1733.  
  1734.  
  1735. //-----------------------------------------------------------------------------
  1736. // CDropShapeCommand::CaptureCommandState
  1737. //
  1738. //-----------------------------------------------------------------------------
  1739.  
  1740. void CDropShapeCommand::CaptureCommandState(Environment* ev)
  1741. {
  1742.     // Create a new list
  1743.     fSavedShapes = new COrderedList;
  1744.     
  1745.     // Save shapes that were just dropped
  1746.     COrdListIterator ite(fSelection->GetShapeList());
  1747.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  1748.     {
  1749.         if (!shape->IsSubscribed())
  1750.             fSavedShapes->AddLast(shape);
  1751.     }
  1752.  
  1753.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  1754.     fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
  1755. }
  1756.  
  1757.  
  1758. //-----------------------------------------------------------------------------
  1759. // CDropShapeCommand::UndoCommand
  1760. //-----------------------------------------------------------------------------
  1761.  
  1762. void CDropShapeCommand::UndoCommand(Environment* ev)
  1763. {
  1764.     if (fDroppedInSameFrame && fDropResult == kODDropMove)    // it's a drag-move
  1765.     {
  1766.         // select dropped shapes and move them back to the original position
  1767.         this->SelectDroppedShapes(ev);
  1768.         fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), -fDropOffset.x, -fDropOffset.y);
  1769.         
  1770.         fSelection->SelectedContentUpdated(ev);
  1771.     }
  1772.     else
  1773.     {
  1774.         // select dropped shapes and remove them from the document
  1775.         this->SelectDroppedShapes(ev);
  1776.         fSelection->SetInLimbo(ev, kODTrue);
  1777.         fSelection->ClearSelection(ev, fSourceFacet->GetFrame(ev));
  1778.     }
  1779. }
  1780.  
  1781. //-----------------------------------------------------------------------------
  1782. // CDropShapeCommand::RedoCommand
  1783. //-----------------------------------------------------------------------------
  1784.  
  1785. void CDropShapeCommand::RedoCommand(Environment* ev)
  1786. {
  1787.     if (fDroppedInSameFrame && fDropResult == kODDropMove)    // it's a drag-move
  1788.     {
  1789.         // select dropped shapes and move them to new position
  1790.         this->SelectDroppedShapes(ev);
  1791.         fSelection->OffsetSelection(ev, fSourceFacet->GetFrame(ev), fDropOffset.x, fDropOffset.y);
  1792.         fSelection->SelectedContentUpdated(ev);
  1793.     }
  1794.     else    // dropped shapes are copies
  1795.     {
  1796.         // add dropped shapes back into document
  1797.         COrdListIterator ite(fSavedShapes);
  1798.         for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  1799.         {
  1800.             // Add the shape to the content list
  1801.             fDrawEditor->AddShape(ev, shape);
  1802.             
  1803.             // Then, add back into selection
  1804.             fSelection->AddToSelection(ev, shape, kODTrue);
  1805.         }
  1806.         
  1807.         COrdListIterator iter2(fSubscribeLinks);
  1808.         for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  1809.             iter2.IsNotComplete(); 
  1810.             link = (CSubscribeLink*)iter2.Next())
  1811.         {
  1812.             link->AddToPart(ev);
  1813.             link->AddToSelection(ev, kODFalse);
  1814.         }
  1815.             
  1816.         COrdListIterator iter3(fPublishLinks);
  1817.         for (CPublishLink* plink = (CPublishLink*)iter3.First();
  1818.             iter3.IsNotComplete(); 
  1819.             plink = (CPublishLink*)iter3.Next())
  1820.         {
  1821.             plink->AddToPart(ev);
  1822.         }
  1823.     
  1824.         fDrawEditor->ContentUpdated(ev, kODNULL);
  1825.     }
  1826.     
  1827. }
  1828.  
  1829. //-----------------------------------------------------------------------------
  1830. // CDropShapeCommand::SelectDroppedShapes
  1831. //-----------------------------------------------------------------------------
  1832.  
  1833. void CDropShapeCommand::SelectDroppedShapes(Environment* ev)
  1834. {
  1835.     fSelection->CloseSelection(ev);
  1836.     
  1837.     COrdListIterator iter(fSavedShapes);
  1838.     for (CShape* shape = (CShape*)iter.First();
  1839.         iter.IsNotComplete(); 
  1840.         shape = (CShape*)iter.Next())
  1841.     {
  1842.         fSelection->AddToSelection(ev, shape, kODFalse);
  1843.     }
  1844.  
  1845.     COrdListIterator iter2(fSubscribeLinks);
  1846.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  1847.         iter2.IsNotComplete(); 
  1848.         link = (CSubscribeLink*)iter2.Next())
  1849.     {
  1850.         link->AddToSelection(ev, kODFalse);
  1851.     }
  1852. }
  1853.  
  1854.  
  1855. //-----------------------------------------------------------------------------
  1856. // CDropShapeCommand::ExecuteDrop
  1857. //-----------------------------------------------------------------------------
  1858.  
  1859. void CDropShapeCommand::ExecuteDrop(Environment* ev)
  1860. {
  1861.     ODStorageUnit *dropSU;
  1862.     ODPoint originPoint;
  1863.  
  1864.     ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
  1865.     ODULong        attributes = drag->GetDragAttributes(ev);
  1866.  
  1867.     // Get the drop result from D&D
  1868.     fDropResult = ((attributes & kODDropIsMove) ? kODDropMove : kODDropCopy);
  1869.  
  1870.     fDroppedInSameFrame = attributes & kODDropIsInSourceFrame;
  1871.     
  1872.     this->GetDropOrigin(ev, &originPoint);
  1873.     
  1874.     // ----- Iterate thru dropped items
  1875.     for (dropSU = fDropInfo->First(ev); dropSU && fDropResult!=kODDropFail;
  1876.             dropSU = fDropInfo->Next(ev))
  1877.     {        
  1878.         // The drop originated within our frame, so we can be smart
  1879.         // and just offset the selection
  1880.         if (fDroppedInSameFrame && (fDropResult == kODDropMove))
  1881.         {
  1882.             if (!this->DoDroppedInSameFrame(ev, dropSU, originPoint, fDropPoint))
  1883.                 fDropResult = kODDropFail;
  1884.             
  1885.             // Actually, this causes source links that are moved in their entirety to update
  1886.             // unecessarily.  We need a parameter to SelectedContentUpdated that determines
  1887.             // whether or not a change should affect fully selected source links.
  1888.             
  1889.             fSelection->SelectedContentUpdated(ev);
  1890.         }
  1891.         else
  1892.         {
  1893.             // Ok, the drop came from somewhere else..
  1894.             
  1895.             // So, Empty the selection
  1896.             fSelection->CloseSelection(ev);
  1897.             
  1898.             // Determine the clone kind based on the drop result
  1899.             ODCloneKind kind = (GetDropResult() == kODDropMove) ? kODCloneDropMove : kODCloneDropCopy;
  1900.             
  1901.             // D&D storage is in the from draft
  1902.             ODDraft*    fromDraft = dropSU->GetDraft(ev);
  1903.             
  1904.             // Build clone info to pass to internalize
  1905.             CCloneInfo info(0, fromDraft, fSourceFacet->GetFrame(ev), kind);
  1906.             
  1907.             // If we internalization fails, DoCommand will set drop result to fail.
  1908.             fSelection->HandleInternalizeContent(ev, dropSU, &info);
  1909.  
  1910.             // Adjust the selection for the drop
  1911.             ODPoint newPosition(fDropPoint.x, fDropPoint.y);
  1912.             
  1913.             ODRect box;
  1914.             fSelection->GetSelectionRectangle(&box);
  1915.         
  1916.             fSelection->OffsetSelection(ev, 
  1917.                                         fSourceFacet->GetFrame(ev), 
  1918.                                         newPosition.x - box.left, 
  1919.                                         newPosition.y - box.top);
  1920.  
  1921.             fDrawEditor->ContentUpdated(ev, kODNULL);
  1922.         }
  1923.     }
  1924.     
  1925.     // ----- Notify DrawEditor that the drop has completed so that
  1926.     // the drag hilite will be erased.
  1927.     fDrawEditor->DropCompleted(ev, fDrawEditor->GetODPart(), fDropResult);
  1928. }
  1929.  
  1930. //=============================================================================
  1931. // CDropAsCommand::CDropAsCommand
  1932. //=============================================================================
  1933.  
  1934. //-----------------------------------------------------------------------------
  1935. // CDropAsCommand::CDropAsCommand
  1936. //-----------------------------------------------------------------------------
  1937.  
  1938. CDropAsCommand::CDropAsCommand(DrawEditor* theEditor,
  1939.                     ODFacet* sourceFacet,
  1940.                     ODDragItemIterator* dropInfo,
  1941.                     CSelection* selection,
  1942.                     ODPoint& dropPoint,
  1943.                     ODBoolean doEmbed) :
  1944. CDropShapeCommand(theEditor,  sourceFacet, dropInfo, selection, dropPoint, kODTrue)
  1945. {
  1946.     fDoEmbed = doEmbed;
  1947. }
  1948.  
  1949.  
  1950.  
  1951. //-----------------------------------------------------------------------------
  1952. // CDropAsCommand::~CDropAsCommand
  1953. //-----------------------------------------------------------------------------
  1954.  
  1955. CDropAsCommand::~CDropAsCommand()
  1956. {
  1957. }
  1958.  
  1959. //-----------------------------------------------------------------------------
  1960. // CDropAsCommand::ExecuteDrop
  1961. //-----------------------------------------------------------------------------
  1962.  
  1963. void CDropAsCommand::ExecuteDrop(Environment* ev)
  1964. {
  1965.     ODStorageUnit *dropSU;
  1966.     ODPoint originPoint;
  1967.  
  1968.     ODDragAndDrop* drag = fDrawEditor->GetSession(ev)->GetDragAndDrop(ev);
  1969.     ODULong        attributes = drag->GetDragAttributes(ev);
  1970.  
  1971.     // Get the drop result from D&D
  1972.     fDropResult = ((attributes & kODDropIsMove) ? kODDropMove : kODDropCopy);
  1973.  
  1974.     fDroppedInSameFrame = attributes & kODDropIsInSourceFrame;
  1975.     
  1976.     this->GetDropOrigin(ev, &originPoint);
  1977.     
  1978.     // ----- Iterate thru dropped items
  1979.     for (dropSU = fDropInfo->First(ev); dropSU && fDropResult!=kODDropFail;
  1980.             dropSU = fDropInfo->Next(ev))
  1981.     {        
  1982.             // So, Empty the selection
  1983.             fSelection->CloseSelection(ev);
  1984.             
  1985.             // Determine the clone kind based on the drop result
  1986.             ODCloneKind kind = (GetDropResult() == kODDropMove) ? kODCloneDropMove : kODCloneDropCopy;
  1987.             
  1988.             // D&D storage is in the from draft
  1989.             ODDraft*    fromDraft = dropSU->GetDraft(ev);
  1990.             
  1991.             // Build clone info to pass to internalize
  1992.             CCloneInfo info(0, fromDraft, fSourceFacet->GetFrame(ev), kind);
  1993.             
  1994.             // If we internalization fails, DoCommand will set drop result to fail.
  1995.             fSelection->HandleTranslateContent(ev, dropSU, &info, fDoEmbed);
  1996.  
  1997.             // Adjust the selection for the drop
  1998.             ODPoint newPosition(fDropPoint.x, fDropPoint.y);
  1999.             
  2000.             ODRect box;
  2001.             fSelection->GetSelectionRectangle(&box);
  2002.         
  2003.             fSelection->OffsetSelection(ev, 
  2004.                                         fSourceFacet->GetFrame(ev), 
  2005.                                         newPosition.x - box.left, 
  2006.                                         newPosition.y - box.top);
  2007.  
  2008.             fDrawEditor->ContentUpdated(ev, kODNULL);
  2009.     }
  2010.     
  2011.     // ----- Notify DrawEditor that the drop has completed so that
  2012.     // the drag hilite will be erased.
  2013.     fDrawEditor->DropCompleted(ev, fDrawEditor->GetODPart(), fDropResult);
  2014. }
  2015.  
  2016.  
  2017.  
  2018. //=============================================================================
  2019. // CCutCopyClearShapeCommand::CCutCopyClearShapeCommand
  2020. //=============================================================================
  2021.  
  2022. //-----------------------------------------------------------------------------
  2023. // CCutCopyClearShapeCommand::CCutCopyClearShapeCommand
  2024. //-----------------------------------------------------------------------------
  2025.  
  2026. CCutCopyClearShapeCommand::CCutCopyClearShapeCommand(DrawEditor* theEditor,
  2027.                                             ODFrame* sourceFrame,
  2028.                                             CSelection* selection,
  2029.                                             ODCommandID command) :
  2030. CCommand(theEditor,  kODFalse, kODFalse, kUndoCopyIndex, kRedoCopyIndex)
  2031. {
  2032.     fSavedShapes = kODNULL;
  2033.     fPublishLinks = kODNULL;
  2034.     fSubscribeLinks = kODNULL;
  2035.     
  2036.     fSelection = selection;
  2037.     fSourceFrame = sourceFrame;
  2038.     fCommandID = command;
  2039.     
  2040.     fUpdateID = kODNULLID;
  2041.     
  2042.     // Cut operations are undoable and change content
  2043.     if (fCommandID!=kODCommandCopy)
  2044.     {
  2045.         fCanUndo = kODTrue;
  2046.         fChangesContent = kODTrue;
  2047.     }
  2048.  
  2049.     // Create clone info
  2050.     if (fCommandID==kODCommandCopy)
  2051.         fCloneKind = kODCloneCopy;
  2052.     else
  2053.         fCloneKind = kODCloneCut;
  2054. }
  2055.  
  2056.  
  2057.  
  2058. //-----------------------------------------------------------------------------
  2059. // CCutCopyClearShapeCommand::~CCutCopyClearShapeCommand
  2060. //-----------------------------------------------------------------------------
  2061.  
  2062. CCutCopyClearShapeCommand::~CCutCopyClearShapeCommand()
  2063. {
  2064.     if (fSavedShapes)
  2065.         delete fSavedShapes;
  2066.         
  2067.     delete fPublishLinks;
  2068.     delete fSubscribeLinks;
  2069. }
  2070.  
  2071.  
  2072. //-----------------------------------------------------------------------------
  2073. // CCutCopyClearShapeCommand::SelectCutShapes
  2074. //-----------------------------------------------------------------------------
  2075.  
  2076. void CCutCopyClearShapeCommand::SelectCutShapes(Environment* ev)
  2077. {
  2078.     fSelection->CloseSelection(ev);
  2079.     
  2080.     COrdListIterator iter(fSavedShapes);
  2081.     for (CShape* shape = (CShape*)iter.First();
  2082.         iter.IsNotComplete(); 
  2083.         shape = (CShape*)iter.Next())
  2084.     {
  2085.         fSelection->AddToSelection(ev, shape, kODFalse);
  2086.     }
  2087.     
  2088.     COrdListIterator iter2(fSubscribeLinks);
  2089.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  2090.         iter2.IsNotComplete(); 
  2091.         link = (CSubscribeLink*)iter2.Next())
  2092.     {
  2093.         link->AddToSelection(ev, kODFalse);
  2094.     }
  2095. }
  2096.  
  2097.  
  2098. //-----------------------------------------------------------------------------
  2099. // CCutCopyClearShapeCommand::DoCommand
  2100. //-----------------------------------------------------------------------------
  2101.  
  2102. void CCutCopyClearShapeCommand::DoCommand(Environment* ev)
  2103. {
  2104.     // Call inherited
  2105.     CCommand::DoCommand(ev);
  2106.     
  2107.     // If any of the shapes in the selection we are operating on have
  2108.     // already been promised t othe clipboard, then we need to resolve
  2109.     // the promise on the clipoard to ensure that it will not be corrupted.
  2110.     if (fSelection->IsPromisedToClipboard())
  2111.     {
  2112.         ::ResolveClipboardPromises(ev, fDrawEditor->GetSession(ev));
  2113.     }
  2114.     
  2115.     // Capture the update id, to be checked in redo, undo
  2116.     if (fCommandID!=kODCommandClear)
  2117.         this->WriteShapesToClipboard(ev);
  2118.     
  2119.     // If this is a cut/clear operation then cut away the shapes
  2120.     if (fCommandID!=kODCommandCopy)
  2121.     {
  2122.         // Mark any embedded content as removed ( "Limbo" )
  2123.         fSelection->SetInLimbo(ev, kODTrue);
  2124.         
  2125.         // Clear the selection
  2126.         fSelection->ClearSelection(ev, fSourceFrame);
  2127.     }
  2128.  
  2129.     // notify clipboard of action done status
  2130.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2131.     fUpdateID = clip->ActionDone(ev, fCloneKind);
  2132. }
  2133.  
  2134.  
  2135. //-----------------------------------------------------------------------------
  2136. // CCutCopyClearShapeCommand::WriteShapesToClipboard
  2137. //-----------------------------------------------------------------------------
  2138.  
  2139. void CCutCopyClearShapeCommand::WriteShapesToClipboard(Environment* ev)
  2140. {
  2141.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2142.     
  2143.     // Remove existing clipboard data
  2144.     clip->Clear(ev);
  2145.     
  2146.     // Get the clipboard content storage unit
  2147.     ODStorageUnit* clipSU = clip->GetContentStorageUnit(ev);
  2148.             
  2149.     CCloneInfo info(0, fDrawEditor->GetDraft(ev), fSourceFrame, fCloneKind);
  2150.     ODUpdateID updateID = clip->GetUpdateID(ev);
  2151.     ODLinkSpec* linkSpec = NULL;
  2152.     ODBoolean doPublish = (fCommandID == kODCommandCopy) && fSelection->CanPublish();
  2153.     
  2154.     ODVolatile(linkSpec);
  2155.         
  2156.     TRY
  2157.     
  2158.         CEmbeddingShape* tShape = fSelection->IsOneEmbeddedShape(ev);
  2159.         if (tShape)
  2160.         {
  2161.             ODFrame* embeddedFrame = tShape->
  2162.                     GetEmbeddedFacet(ev, fSourceFrame)->GetFrame(ev);
  2163.                     
  2164.             fSelection->ExternalizeSingleEmbeddedFrame( ev, 
  2165.                                                         clipSU, 
  2166.                                                         &info, 
  2167.                                                         embeddedFrame);
  2168.         }
  2169.         else
  2170.         {
  2171.             // Focus to the content property
  2172.             ODSUForceFocus(ev, clipSU, kODPropContents, kDrawEditorKind);
  2173.         
  2174.             CClipboardPromise* promise = new CClipboardPromise(fDrawEditor, 
  2175.                                 fSourceFrame, fSelection, fCloneKind, updateID );
  2176.             
  2177.             // Promise the data
  2178.             promise->Promise(ev, clipSU);
  2179.         }
  2180.     
  2181.         if (doPublish)
  2182.         {
  2183.             // See the comment in CDragShapeCommand::Drag for complete explanation.  In this case
  2184.             // a null command pointer in the spec will trigger CreateLink to create a CCreateLinkCommand
  2185.             // for undo/redo.
  2186.             LinkSpecData  specData = {updateID, (CDragShapeCommand*)kODNULL};
  2187.         
  2188.             ODByteArray data;
  2189.             data._buffer = (octet*)&specData;
  2190.             data._length = sizeof(specData);
  2191.             data._maximum = sizeof(specData);
  2192.     
  2193.             linkSpec = fDrawEditor->GetDraft(ev)->CreateLinkSpec(ev, fDrawEditor->GetODPart(), &data);
  2194.  
  2195.             clipSU->AddProperty(ev, kODPropLinkSpec);
  2196.             linkSpec->WriteLinkSpec(ev, clipSU);
  2197.             delete linkSpec;
  2198.         }
  2199.     
  2200.     CATCH_ALL
  2201.         // If an exception was raised then clear the clipboard.
  2202.         // The previous contents of the clipboard are lost.
  2203.         clip->Clear(ev);
  2204.         
  2205.         if (linkSpec)
  2206.             delete linkSpec;
  2207.             
  2208.         doPublish = kODFalse;
  2209.     ENDTRY
  2210.  
  2211.     if (doPublish)
  2212.     {
  2213.         // If current selection is already published, just re-use its publisher
  2214.         CPublishLink* publishLink = fSelection->FindPublisher();
  2215.         
  2216.         if (publishLink)
  2217.             publishLink->SetPendingID(updateID);
  2218.         else
  2219.         {
  2220.             // since never create a publisher for a cut, we can let the new publish links have 
  2221.             // our shape and subscribe link lists without copying them. (Copy is not undoable)
  2222.             publishLink = new CPublishLink(updateID, fSelection, fSavedShapes, fSubscribeLinks);
  2223.             
  2224.             // The new link is now responsible for these.
  2225.             fSavedShapes = kODNULL;
  2226.             fSubscribeLinks = kODNULL;
  2227.         }
  2228.             
  2229.         fDrawEditor->SetPendingPublish(publishLink);
  2230.     }
  2231. }
  2232.  
  2233.  
  2234. //-----------------------------------------------------------------------------
  2235. // CCutCopyClearShapeCommand::UndoCommand
  2236. //-----------------------------------------------------------------------------
  2237.  
  2238. void CCutCopyClearShapeCommand::UndoCommand(Environment* ev)
  2239. {
  2240.     // Call Inherited
  2241.     CCommand::UndoCommand(ev);
  2242.         
  2243.     // We should never get here unless this is a cut operation
  2244.     COrdListIterator iter(fSavedShapes);
  2245.     for (CShape* shape = (CShape*)iter.First();
  2246.         iter.IsNotComplete(); 
  2247.         shape = (CShape*)iter.Next())
  2248.     {
  2249.         fDrawEditor->AddShape(ev, shape);
  2250.     }
  2251.  
  2252.     COrdListIterator iter2(fSubscribeLinks);
  2253.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  2254.         iter2.IsNotComplete(); 
  2255.         link = (CSubscribeLink*)iter2.Next())
  2256.     {
  2257.         link->AddToPart(ev);
  2258.     }
  2259.  
  2260.     this->SelectCutShapes(ev);
  2261.  
  2262.     // Call selection changed before adding back any publishers. That way, 
  2263.     // They won't be updated. Publishers that are entirely contained in content
  2264.     // being removed should not propagate updates, therefore don't need to when they
  2265.     // are added back in again.
  2266.     
  2267.     // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  2268.     fSelection->SelectedContentUpdated(ev);
  2269.     
  2270.     COrdListIterator iter3(fPublishLinks);
  2271.     for (CPublishLink* plink = (CPublishLink*)iter3.First();
  2272.         iter3.IsNotComplete(); 
  2273.         plink = (CPublishLink*)iter3.Next())
  2274.     {
  2275.         plink->AddToPart(ev);
  2276.     }
  2277.     
  2278.     fDrawEditor->ContentUpdated(ev, kODNULL);
  2279.     
  2280.     // notify clipboard of action done status
  2281.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2282.     clip->ActionUndone(ev, fUpdateID, fCloneKind);
  2283. }
  2284.  
  2285.  
  2286. //-----------------------------------------------------------------------------
  2287. // CCutCopyClearShapeCommand::RedoCommand
  2288. //-----------------------------------------------------------------------------
  2289.  
  2290. void CCutCopyClearShapeCommand::RedoCommand(Environment* ev)
  2291. {
  2292.     // Call Inherited
  2293.     CCommand::RedoCommand(ev);
  2294.     
  2295.     this->SelectCutShapes(ev);
  2296.     
  2297.     // If this is a cut operation then cut away the shapes
  2298.     if (fCommandID!=kODCommandCopy)
  2299.     {
  2300.         // Mark any embedded content as removed ( "Limbo" )
  2301.         fSelection->SetInLimbo(ev, kODTrue);
  2302.         
  2303.         // Clear the selection
  2304.         fSelection->ClearSelection(ev, fSourceFrame);
  2305.     }
  2306.     
  2307.     // notify clipboard of action done status
  2308.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2309.     clip->ActionRedone(ev, fUpdateID, fCloneKind);
  2310. }
  2311.  
  2312.  
  2313. //-----------------------------------------------------------------------------
  2314. // CCutCopyClearShapeCommand::Commit
  2315. //
  2316. // Here you want to clean up command specific structures depnding on the value of state.
  2317. // For example, if a command creates a new piece of content and is comitted after being undone
  2318. // then it should delete the structure representing the new content. Otherwise, it should not
  2319. // deleted.
  2320. //-----------------------------------------------------------------------------
  2321.  
  2322. void CCutCopyClearShapeCommand::Commit(Environment* ev, ODDoneState state)
  2323. {
  2324.     CCommand::Commit(ev, state);
  2325.     
  2326.     if ( (state != kODUndone) && (fCommandID != kODCommandCopy) )
  2327.     {
  2328.         
  2329.         // Before removing / deleting shapes check to see if they
  2330.         // are promised to the clipboard.
  2331.         ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
  2332.         
  2333.         COrdListIterator iter(fSavedShapes);
  2334.         for (CShape* shape = (CShape*)iter.First();
  2335.             iter.IsNotComplete(); 
  2336.             shape = (CShape*)iter.Next())
  2337.         {
  2338.             shape->Removed(ev, kCommit);
  2339.             delete shape;
  2340.         }
  2341.  
  2342.         while (fSubscribeLinks->Count() != 0)
  2343.         {
  2344.             CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
  2345.             link->RemoveShapes(ev, kCommit);
  2346.             delete link;
  2347.         }
  2348.  
  2349.         while (fPublishLinks->Count() != 0)
  2350.         {
  2351.             CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
  2352.             delete link;
  2353.         }
  2354.  
  2355.     }
  2356. }
  2357.  
  2358.  
  2359. //-----------------------------------------------------------------------------
  2360. // CCutCopyClearShapeCommand::CaptureCommandState
  2361. //
  2362. // Here you want to save off any state info necessary for the command to be able to undo/redo.
  2363. // Example: You might make a copy of a list of references to content that is being operated on
  2364. // by the command.
  2365. //-----------------------------------------------------------------------------
  2366.  
  2367. void CCutCopyClearShapeCommand::CaptureCommandState(Environment* ev)
  2368. {
  2369.     // Only a cut/clear is undo-able, but a copy needs to make the shape and subscribe 
  2370.     // link lists available to the pending publish link.
  2371.     fSavedShapes = new COrderedList;
  2372.     COrdListIterator iter(fSelection->GetShapeList());
  2373.     for (CShape* shape = (CShape*)iter.First();
  2374.         iter.IsNotComplete(); 
  2375.         shape = (CShape*)iter.Next())
  2376.     {
  2377.         if (!shape->IsSubscribed())
  2378.             fSavedShapes->AddLast(shape);
  2379.     }
  2380.     
  2381.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  2382.  
  2383.     // Set the menu text IDs for the right command 
  2384.     if (fCommandID != kODCommandCopy)
  2385.     {
  2386.         fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
  2387.         if (fCommandID==kODCommandCut)
  2388.             this->SetMenuTextIDs(kUndoCutIndex, kRedoCutIndex);
  2389.         else
  2390.             this->SetMenuTextIDs(kUndoClearIndex, kRedoClearIndex);
  2391.     }
  2392.     else
  2393.         this->SetMenuTextIDs(kUndoCopyIndex, kRedoCopyIndex);
  2394. }
  2395.  
  2396.  
  2397. //=============================================================================
  2398. // CPasteCommand::CPasteCommand
  2399. //=============================================================================
  2400.  
  2401. //-----------------------------------------------------------------------------
  2402. // CPasteCommand::CPasteCommand
  2403. //-----------------------------------------------------------------------------
  2404.  
  2405. CPasteCommand::CPasteCommand(DrawEditor* theEditor,
  2406.                                         ODFrame* sourceFrame,
  2407.                                         CSelection* selection) :
  2408. CCommand(theEditor,  kODTrue, kODTrue, kUndoPasteIndex, kRedoPasteIndex)
  2409. {
  2410.     fSelection = selection;
  2411.     fSourceFrame = sourceFrame;
  2412.     
  2413.     fUpdateID = kODNULLID;
  2414.     
  2415.     fSavedShapes = kODNULL;
  2416.     fPublishLinks = kODNULL;
  2417.     fSubscribeLinks = kODNULL;
  2418. }
  2419.  
  2420. //-----------------------------------------------------------------------------
  2421. // CPasteCommand::~CPasteCommand
  2422. //-----------------------------------------------------------------------------
  2423.  
  2424. CPasteCommand::~CPasteCommand()
  2425. {
  2426.     if (fSavedShapes)
  2427.         delete fSavedShapes;
  2428.         
  2429.     delete fPublishLinks;
  2430.     delete fSubscribeLinks;
  2431. }
  2432.  
  2433.  
  2434. //-----------------------------------------------------------------------------
  2435. // CPasteCommand::HandlePaste
  2436. //-----------------------------------------------------------------------------
  2437.  
  2438. void CPasteCommand::HandlePaste(Environment* ev)
  2439. {    
  2440.     // Get the clipboard storage unit and internalize it
  2441.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2442.     
  2443.     // Get the clipboard content storage unit
  2444.     ODStorageUnit* contentSU = clip->GetContentStorageUnit(ev);
  2445.         
  2446.     // The clone kind is paste
  2447.     ODCloneKind kind =  kODClonePaste;
  2448.     
  2449.     // D&D storage is in the from draft
  2450.     ODDraft*    fromDraft = contentSU->GetDraft(ev);
  2451.     
  2452.     // Build clone info to pass to internalize
  2453.     CCloneInfo info(0, fromDraft, fSourceFrame, kind);
  2454.     
  2455.     TRY
  2456.         fSelection->HandleInternalizeContent(ev, contentSU, &info);
  2457.     CATCH_ALL
  2458.         DebugStr("\pFailure to internlalize paste!");
  2459.     ENDTRY
  2460.  
  2461.     // Transform the shape for the paste
  2462.     ODPoint newPosition(100, 100);            // DCS $$$$$ Change to constant/function
  2463.  
  2464.     fSelection->OffsetSelection(ev, fSourceFrame, newPosition.x, newPosition.y);
  2465.     
  2466.     // Save shapes that were just dropped
  2467.     COrdListIterator ite(fSelection->GetShapeList());
  2468.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  2469.     {
  2470.         if (!shape->IsSubscribed())
  2471.             fSavedShapes->AddLast(shape);
  2472.     }
  2473.     
  2474.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  2475.     fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
  2476.     
  2477.     // Here we actually add any just internalized subscribe links to the part.  Doing so
  2478.     // may cause the some links to be immediately updated. That would be bad if done while
  2479.     // on directly by the selection on it's list of links, because the update closes the 
  2480.     // current selection, thus clearing the list in the process.
  2481.     
  2482.     COrdListIterator iter(fSubscribeLinks);
  2483.     for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
  2484.         iter.IsNotComplete(); 
  2485.         link = (CSubscribeLink*)iter.Next())
  2486.     {
  2487.         link->AddToPart(ev);
  2488.     }
  2489. }
  2490.  
  2491.  
  2492. //-----------------------------------------------------------------------------
  2493. // CPasteCommand::DoCommand
  2494. //-----------------------------------------------------------------------------
  2495.  
  2496. void CPasteCommand::DoCommand(Environment* ev)
  2497. {    
  2498.  
  2499.     // Resolve the drop before we set the action history
  2500.     CCommand::DoCommand(ev);
  2501.     
  2502.     // Empty the selection
  2503.     fSelection->CloseSelection(ev);
  2504.  
  2505.     // Do the paste
  2506.     this->HandlePaste(ev);
  2507.     
  2508.     // notify clipboard of action done status
  2509.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2510.     fUpdateID = clip->ActionDone(ev, kODClonePaste);
  2511. }
  2512.  
  2513.  
  2514. //-----------------------------------------------------------------------------
  2515. // CPasteCommand::Commit
  2516. //
  2517. // Here you want to clean up command specific structures depending on the value of state.
  2518. // For example, if a command creates a new piece of content and is comitted after being undone
  2519. // then it should delete the structure representing the new content. Otherwise, it should not
  2520. // deleted.
  2521. //-----------------------------------------------------------------------------
  2522.  
  2523. void CPasteCommand::Commit(Environment* ev, ODDoneState state)
  2524. {
  2525.     CCommand::Commit(ev, state);
  2526.     
  2527.     // If the command was Done or Redone and it was not a drop move 
  2528.     // ( shapes were dragged out of document ) then we should delete the 
  2529.     // shapes in the saved shape list.
  2530.     if ((state==kODUndone))
  2531.     {
  2532.         // Before removing / deleting shapes check to see if they
  2533.         // are promised to the clipboard.
  2534.         ::CheckAndResolvePromisedShapes(ev, fSavedShapes, fDrawEditor->GetSession(ev));
  2535.         
  2536.         COrdListIterator iter(fSavedShapes);
  2537.         for (CShape* shape = (CShape*)iter.First();
  2538.             iter.IsNotComplete(); 
  2539.             shape = (CShape*)iter.Next())
  2540.         {
  2541.             shape->Removed(ev, kCommit);
  2542.             delete shape;
  2543.         }
  2544.         
  2545.         while (fSubscribeLinks->Count() != 0)
  2546.         {
  2547.             CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
  2548.             link->RemoveShapes(ev, kCommit);
  2549.             delete link;
  2550.         }
  2551.         
  2552.         while (fPublishLinks->Count() != 0)
  2553.         {
  2554.             CPublishLink* link = (CPublishLink*)fPublishLinks->RemoveFirst();
  2555.             delete link;
  2556.         }
  2557.  
  2558.     }
  2559.  
  2560. }
  2561.  
  2562.  
  2563. //-----------------------------------------------------------------------------
  2564. // CPasteCommand::CaptureCommandState
  2565. //
  2566. //-----------------------------------------------------------------------------
  2567.  
  2568. void CPasteCommand::CaptureCommandState(Environment* ev)
  2569. {
  2570.     // Create a new list
  2571.     fSavedShapes = new COrderedList;
  2572. }
  2573.  
  2574.  
  2575. //-----------------------------------------------------------------------------
  2576. // CPasteCommand::UndoCommand
  2577. //-----------------------------------------------------------------------------
  2578.  
  2579. void CPasteCommand::UndoCommand(Environment* ev)
  2580. {
  2581.     // select pasted shapes and remove them from the document
  2582.     this->SelectPastedShapes(ev);
  2583.     
  2584.     fSelection->SetInLimbo(ev, kODTrue);
  2585.     fSelection->ClearSelection(ev, fSourceFrame);
  2586.     
  2587.     // Clear selection calls ContentUpdated.
  2588.     
  2589.     // notify clipboard of action done status
  2590.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2591.     clip->ActionUndone(ev, fUpdateID, kODClonePaste);
  2592. }
  2593.  
  2594. //-----------------------------------------------------------------------------
  2595. // CPasteCommand::RedoCommand
  2596. //-----------------------------------------------------------------------------
  2597.  
  2598. void CPasteCommand::RedoCommand(Environment* ev)
  2599. {
  2600.     // add dropped shapes back into document
  2601.     COrdListIterator ite(fSavedShapes);
  2602.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  2603.     {
  2604.         // Add the shape to the content list
  2605.         fDrawEditor->AddShape(ev, shape);
  2606.         fSelection->AddToSelection(ev, shape, kODTrue);
  2607.     }
  2608.         
  2609.     COrdListIterator iter2(fSubscribeLinks);
  2610.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  2611.         iter2.IsNotComplete(); 
  2612.         link = (CSubscribeLink*)iter2.Next())
  2613.     {
  2614.         link->AddToPart(ev);
  2615.         link->AddToSelection(ev, kODFalse);
  2616.     }
  2617.  
  2618.     // (MH)  Call selection changed before adding back any publishers. That way, 
  2619.     // They won't be updated. Publishers that are entirely contained in content
  2620.     // being removed/replaced don't need to propagate any updates.
  2621.     
  2622.     // fFrame->GetPresentation(ev)->Invalidate(ev, fDrawSelection->GetUpdateShape());
  2623.     fSelection->SelectedContentUpdated(ev);
  2624.     
  2625.     COrdListIterator iter3(fPublishLinks);
  2626.     for (CPublishLink* plink = (CPublishLink*)iter3.First();
  2627.         iter3.IsNotComplete(); 
  2628.         plink = (CPublishLink*)iter3.Next())
  2629.     {
  2630.         plink->AddToPart(ev);
  2631.     }
  2632.  
  2633.     fDrawEditor->ContentUpdated(ev, kODNULL);
  2634.     
  2635.     // notify clipboard of action done status
  2636.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2637.     clip->ActionRedone(ev, fUpdateID, kODClonePaste);
  2638. }
  2639.  
  2640. //-----------------------------------------------------------------------------
  2641. // CPasteCommand::SelectPastedShapes
  2642. //-----------------------------------------------------------------------------
  2643.  
  2644. void CPasteCommand::SelectPastedShapes(Environment* ev)
  2645. {
  2646.     fSelection->CloseSelection(ev);
  2647.     
  2648.     COrdListIterator iter(fSavedShapes);
  2649.     for (CShape* shape = (CShape*)iter.First();
  2650.         iter.IsNotComplete(); 
  2651.         shape = (CShape*)iter.Next())
  2652.     {
  2653.         fSelection->AddToSelection(ev, shape, kODFalse);
  2654.     }
  2655.     
  2656.     COrdListIterator iter2(fSubscribeLinks);
  2657.     for (CSubscribeLink* link = (CSubscribeLink*)iter2.First();
  2658.         iter2.IsNotComplete(); 
  2659.         link = (CSubscribeLink*)iter2.Next())
  2660.     {
  2661.         link->AddToSelection(ev, kODFalse);
  2662.     }
  2663. }
  2664.  
  2665. //=============================================================================
  2666. // CPasteAsCommand::CPasteAsCommand
  2667. //=============================================================================
  2668.  
  2669. //-----------------------------------------------------------------------------
  2670. // CPasteAsCommand::CPasteAsCommand
  2671. //-----------------------------------------------------------------------------
  2672.  
  2673. CPasteAsCommand::CPasteAsCommand(DrawEditor* theEditor,
  2674.                                         ODFrame* sourceFrame,
  2675.                                         CSelection* selection, 
  2676.                                         ODBoolean embedOrMerge) :
  2677. CPasteCommand(theEditor, sourceFrame, selection)
  2678. {
  2679.     fDoEmbed = embedOrMerge;
  2680. }
  2681.  
  2682. //-----------------------------------------------------------------------------
  2683. // CPasteAsCommand::~CPasteAsCommand
  2684. //-----------------------------------------------------------------------------
  2685.  
  2686. CPasteAsCommand::~CPasteAsCommand()
  2687. {
  2688. }
  2689.  
  2690.  
  2691. //-----------------------------------------------------------------------------
  2692. // CPasteAsCommand::HandlePaste
  2693. //-----------------------------------------------------------------------------
  2694.  
  2695. void CPasteAsCommand::HandlePaste(Environment* ev)
  2696. {    
  2697.     // Get the clipboard storage unit and internalize it
  2698.     ODClipboard* clip = fDrawEditor->GetSession(ev)->GetClipboard(ev);
  2699.     
  2700.     // Get the clipboard content storage unit
  2701.     ODStorageUnit* contentSU = clip->GetContentStorageUnit(ev);
  2702.         
  2703.     // The clone kind is paste
  2704.     ODCloneKind kind =  kODClonePaste;
  2705.     
  2706.     // D&D storage is in the from draft
  2707.     ODDraft*    fromDraft = contentSU->GetDraft(ev);
  2708.     
  2709.     // Build clone info to pass to internalize
  2710.     CCloneInfo info(0, fromDraft, fSourceFrame, kind);
  2711.     
  2712.     TRY
  2713.         fSelection->HandleTranslateContent(ev, contentSU, &info, fDoEmbed);
  2714.     CATCH_ALL
  2715.         DebugStr("\pFailure to internlalize paste!");
  2716.     ENDTRY
  2717.  
  2718.     // Transform the shape for the paste
  2719.     ODPoint newPosition(100, 100);            // DCS $$$$$ Change to constant/function
  2720.  
  2721.     fSelection->OffsetSelection(ev, fSourceFrame, newPosition.x, newPosition.y);
  2722.     
  2723.     // Save shapes that were just pasted
  2724.     COrdListIterator ite(fSelection->GetShapeList());
  2725.     for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
  2726.     {
  2727.         if (!shape->IsSubscribed())
  2728.             fSavedShapes->AddLast(shape);
  2729.     }
  2730.     
  2731.     fSubscribeLinks = new COrderedList(fSelection->GetSubscribeLinks());
  2732.     fPublishLinks = new COrderedList(fSelection->GetPublishLinks());
  2733.  
  2734.     // Here we actually add any just internalzied subscribe links to the part.  Doing so
  2735.     // may cause the some links to be immediately updated. That would be bad if done while
  2736.     // on directly by the selection on it's list of links, because the update closes the 
  2737.     // current selection, thus clearing the list in the process.
  2738.     
  2739.     COrdListIterator iter(fSubscribeLinks);
  2740.     for (CSubscribeLink* link = (CSubscribeLink*)iter.First();
  2741.         iter.IsNotComplete(); 
  2742.         link = (CSubscribeLink*)iter.Next())
  2743.     {
  2744.         link->AddToPart(ev);
  2745.     }
  2746. }
  2747.  
  2748.  
  2749.  
  2750.  
  2751.